背景
最近自己写了一个网站玩,在引用别人网站的图片是遇到了一些小问题。
<img src="https://xxxx" alt="">
像这个样子,src后面跟的是别的网站的图片的url。
问题
有的图片在我们发布的网站上能正常加载出来,有的一些就加载不出来,审查一下元素,会看到Failed to load resource: the server responded with a status of 403 ()
的报错。
发现和解决问题
经过了解,发现这是一个叫做防盗链的东西,网站设置了防盗链的策略,会在后台判断请求的Referrer属性是不是来自于一个非本域名的网站,如果来源不是本域名就返回403 forbidden
。我们要做的就是用最方便的方法使得我的页面能够不受他的防盗链策略的影响。我从网上搜到了几个解决方法。
图片预下载
这个是最直观的解决方式了,正在使用别人的图,先把图片下载下来,保存到自己的服务器上,然后就等于是用自己的了~ 如果自己没有服务器,可以去网上找找图床,应该也能解决问题。
删除Header中的Referrer
保证最佳效果的最简单的写法就是在html文件的head中添加一个meta标签<meta name="referrer" content="never" />
为什么叫保证效果的最简单写法 ?下面看一些数据对比。
删除Header中的Referrer的方法也有多种:添加meta标签
和添加ReferrerPolicy属性
添加meta标签
一种方法是给页面添加一个meta标签,在meta标签里指定referrer的值,比如<meta name="referrer" content="xxx" />。网上可以查到各种奇奇怪怪的值,其实我总结了来源于两个地方。
一个是来自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" />
nothing | meta in head referrer=never | meta in head referrer=no-referrer | meta referrer=never | meta referrer=no-referrer | img referrerPolicy=no-referrer | |
---|---|---|---|---|---|---|
Chrome | N | Y | Y | Y | Y | Y |
Firefox | N | Y | Y | N | N | Y |
Edge/IE | N | Y | N | Y | N | N |
可以看出Chrome浏览器对各种写法都支持的最好。Firefox支持所有标准的写法,但是不支持没有写在head标签中的meta标签;Edge/IE则不支持MDN里定义的”no-referrer”配置项,果然是个古董。。。
总的来说,保证最佳效果的最简单的写法就是添加一个meta标签<meta name="referrer" content="never" />,这样就不用考虑浏览器的差别了,虽然这种写法并不被官方推荐(主要还是要迁就IE这个古董,放弃了理论上更为正确的标准)。
使用iframe
这个图片就是使用了防盗链的http://json.image.alimmdn.com/vsou.png
- 建一个空的iframe
- iframe设置src,内容就是图片或一段html
var body = document.querySelector("body");
var iframe = document.createElement("iframe");
var html = '<img src="http://json.image.alimmdn.com/vsou.png"/>';
iframe.src = 'javascript:void(function(){document.open();document.write(\'' + html + '\');document.close();}())';
body.appendChild(iframe);
略微设置一下样式
iframe.style.position="fixed";
iframe.style.width="100%";
iframe.style.height="100%";
iframe.style.border=0;
iframe.style.zIndex=10;
iframe.style.top=0;
iframe.style.left=0;
上面一段代码有一个关键因素,就是在iframe之外,不能有任何其他图片该域名(示例图片所在域名)下的图片,否则功亏一篑
上面的解释是从网上搜到的,没有什么问题,总结起来方法就是我们创建一个iframe,然后把我们要显示的带有防盗链图片链接的html标签,以字符换的形式传给iframe的src属性就行了。
不过这个方法是有问题的,因为iframe设置width和height都无效,所以用在我的网站上样式是不合适的。具体为什么这样,大家可以查一下iframe,具体的了解一下。
参考
https://juejin.im/entry/5adaa72c6fb9a07aa43bc665
https://segmentfault.com/a/1190000004968720
网友评论