很多图片外链都会开启防盗链功能,但是很多时候,直接使用图片地址,是很方便的一件事情。
该如何解决这个矛盾呢?
首先,要理解防盗链原理,是如何判断图片被盗用了?
服务器根据请求头中的referer进行判断,是否属于白名单域名,如果不是,就返回一张裂图或版权信息的图片。
那么能否伪造这个请求头呢?
那又要了解这个referer是什么东西:
Referer是HTTP请求Header的一部分,当浏览器向Web服务器发送请求的时候,请求头信息一般需要包含Referer。该Referer会告诉服务器我是从哪个页面链接过来的,服务器基此可以获得一些信息用于处理。
简单说,就是告诉服务器,请求来自哪里。
所以第三方使用别人的防盗链图片时,就会告诉图片服务器,被盗用了。
这个字段可以通过模拟请求来伪造。但是在浏览器里,这个字段无法伪造。。
所以,清空这个头信息之后,就可以访问了。
又该如何清空一个请求的referer呢?
再看下图,思考一个问题:为什么直接用浏览器打开这个图片地址,可以访问到?
经过查看请求信息发现,直接浏览器打开访问时,没有这个referer字段:
那么,我们是不是可以在使用时,也模仿浏览器,直接访问这张图片呢?就可以不会带上来源了。
所以这里就想到了iframe。
那么又怎样在iframe访问这张图片,又不被带上父页面的来源呢?
在看一个场景:
浏览器会解析data:作为文件打开。其实这种做法,经常被用到。只不过都是data:base64 (图片预览), data:text/plain (文本预览)。
所以就可以使用iframe,打开一个临时的data类型的文件。
<iframe src="data:text/html,<img src='https://xxx.com/xx.jpg'/>"></iframe>
以上代码,基本解决了盗链问题了,还有一个小问题。这样一来,样式就很丑。iframe会有内部滚动条。
当然,这就是小问题了,很好解决了。
let url = 'https://mmbiz.qpic.cn/mmbiz_jpg/MFxNcLSvjr7eWoVtAC3eK2lH894AdAGamIibuxpcFSRmtOtnZNn6Jicg3r9EiaOuviceO4ulU8Yy0icNO8rPNs4DvsA/640?wxtype=jpeg&wxfrom=0'; // 图片地址
// html中尽量使用单引号。
let html = `
<style>
html,body,img{height:100%;width:100%}
body{margin:0}
img{object-fit:cover}
</style>
<img src='${url}'/>
`
html = html.replace(/\n/g,'') // 不能带有换行符,否则解析可能失败。
let iframe = `<iframe src="data:text/html,${html}" style="border:0;"></iframe>`
经过以上处理,完美解决了防盗链的图片的正常使用。
觉得有用,给个赞呗