微信号:phpxs8

介绍:我们怎样才能成为人们心目中的大牛呢?不要复制粘贴,细心、多练、多敲代码.

主流浏览器图片反防盗链方法总结

2018-04-25 22:25 敲代码

作者:Myths

blog.mythsman.com/2018/04/20/1/


前言


还记得之前写的那个无聊的插件,前一段时间由于豆瓣读书增加了防盗链策略使得我们无法直接引用他们的图片,使得我这个小插件无法工作。本以为是一个很简单的问题,但是没想到这个小问题硬是让我改了五六遍才改好,可以说是非常的蠢了。总结一下自己犯傻的原因,还是由于自己懒得去深入研究,谷歌百度了问题就直接把方案拿来用了,浅尝辄止人云亦云,解决了表面的问题而没有深入的总结。当然,从另外一个方面讲,我也是初步领会到了前端程序员面对要兼容各种浏览器的需求时头有多大了。


问题


问题很简单,就是我希望在自己的页面里用<img src="xxxx" />来引用其他网站的一张图片,但是他的网站设置了防盗链的策略,会在后台判断请求的Referrer属性是不是来自于一个非本域名的网站,如果来源不是本域名就返回403 forbidden。我的目的就是用最方便的方法使得我的页面能够不受他的防盗链策略的影响。


解决方案


后台预下载


预下载是最直观的一种方法,既然不能直接引用,那我就先后台下载下来,然后将图片链接到下载后的图片即可。这个方法还是比较稳妥的,图片下载下来就是自己的了,不会再受人限制。不过这总有种侵犯知识产权的感觉,而且每张图片都要后台先下载,逻辑处理起来还是有点麻烦的;而且对于那种纯静态页面,没有后台程序供我们发挥,这也就无法实现了。


第三方代理


第三方代理其实算是后台与下载的升级版,其实就是将下载图片的这个过程交给第三方的网站。一个非常好用的代理是images.weserv.nl,我们可以直接将自己需要“盗链”的图片写在请求中即可。我们甚至可以指定一些简单的图片处理参数,让代理帮我们处理。


比如我想盗链https://foo.com/foo.jpg,并且将图片宽度设置成100,我们就可以直接这样引用:


<img src="https://images.weserv.nl/?url=foo.com/foo.jpg&w=100" />


这还是很方便的,不过美中不足的是这个国外的网站在国内的访问速度似乎有点慢,有时候甚至还会被墙,这就有点尴尬了。


删除Header中的Referrer


相比上面两种折腾的方法,如果能直接修改Referrer,那不就省了很多事了么。但是事实上这里的配置还是有挺多坑的,方法也有很多种,一不小心就会跟我一样踩了一遍又一遍。


添加meta标签


一种方法是给页面添加一个meta标签,在meta标签里指定referrer的值,比如。网上可以查到各种奇奇怪怪的值,其实我总结了来源于两个地方。


一个是来自whatwg的标准。他给meta标签的referrer属性定义了四个值:never,always,origin,default。如果需要关闭referrer,就将referrer的值设置成”never”。这个标准还是比较老的,而且在他的主页上也明确写了”This document is obsolete.”。不过据我调研,或许正是由于这个标准比较老,反而导致绝大多数浏览器对他的支持都很好,因祸得福蛤蛤。


另外一个是来自MDN的标准。他给meta标签的referrer属性定义了五个值,如果要关闭referrer,就将它的值设置成no-referrer。

不过我们需要注意的是,meta标签添加的位置也很重要,有的浏览器能够识别非head标签中的meta标签,有的就不行。在实际使用的时候还要小心,这一点下文会有一个更具体的比较。


添加ReferrerPolicy属性


添加meta标签相当于对文档中的所有链接都取消了referrer,而ReferrerPolicy则更精确的指定了某一个资源的referrer策略。关于这个策略的定义可以参照MDN。比如我想只对某一个图片取消referrer,如下编写即可:


<img src="xxxx.jpg"  referrerPolicy="no-referrer" />


浏览器支持对比


上面我们讲了两种取消referrer头信息的方法,但其实这却对应了五种写法,我们来看下面的对比表:



可以看出Chrome浏览器对各种写法都支持的最好,棒棒哒;Firefox支持所有标准的写法,但是不支持没有写在head标签中的meta标签;Edge/IE则不支持MDN里定义的”no-referrer”配置项,果然是个古董。。。


总的来说,保证最佳效果的最简单的写法就是添加一个meta标签,这样就不用考虑浏览器的差别了,虽然这种写法并不被官方推荐(主要还是要迁就IE这个古董,放弃了理论上更为正确的标准)。


参考资料


  • whatwg

  • MDN

  • 使用Referer Meta标签控制referer

 
敲代码 更多文章 详解 CORS 跨域资源共享 你试过不用if写代码吗? 详解HTML与CSS代码的规范 不依赖框架写出现代化 PHP 代码 从输入url开始能做哪些优化
猜您喜欢 当我们在聊用 iPad Pro 画画的时候,我们在聊什么? 【第3章第338回】投屏类H5应用开发分析 Python学习之模块 头条丨英特尔的小目标:先买它十家公司 数一数,阿里云这次带来了哪些技术升级?