原因以及防盗链
原因:在h5项目中访问第三方api返回的图片链接返回403错误,但是把该url输入浏览器的搜索栏中却可以成功访问。百度一番之后,了解到是第三方的图片链接做了防盗链处理。
防盗链:防盗链的规则一般是先判断请求中的referer信息,如果referer的请求源不在自己白名单内,就返回403或者相应的处理(重定向到别的图片等等)。在nginx中常用的配置如下:
location ~* \.(gif|jpg|jpeg|png|bmp|swf|flv)$ {
valid_referers none blocked 域名/IP;
if ($invalid_referer) {
rewrite ^/ https://xxxxx/404.png;
# return 403;
}
}
解决办法
有问题肯定要解决的,所以我又又百度了一番后成功的找到了解决办法。
方法一:
只需要在html的head中添加以下代码:
<meta name="referrer" content="no-referrer" />
这里贴下MDN中Referrer-Policy的几种值
| 标题 | 含义 |
|---|---|
| no-referrer | 整个 Referer 首部会被移除。访问来源信息不随着请求一起发送。 |
| no-referrer-when-downgrade | 在同等安全级别的情况下,引用页面的地址会被发送(HTTPS->HTTPS),但是在降级的情况下不会被发送 (HTTPS->HTTP)。 |
| origin | 在任何情况下,仅发送文件的源作为引用地址。例如 example.com/page.html 会将 example.com/ 作为引用地址。 |
| origin-when-cross-origin | 对于同源的请求,会发送完整的URL作为引用地址,但是对于非同源请求仅发送文件的源。 |
| same-origin | 对于同源的请求会发送引用地址,但是对于非同源请求则不发送引用地址信息。 |
| strict-origin | 在同等安全级别的情况下,发送文件的源作为引用地址(HTTPS->HTTPS),但是在降级的情况下不会发送 (HTTPS->HTTP)。 |
| strict-origin-when-cross-origin | 对于同源的请求,会发送完整的URL作为引用地址;在同等安全级别的情况下,发送文件的源作为引用地址(HTTPS->HTTPS);在降级的情况下不发送此首部 (HTTPS->HTTP)。 |
| unsafe-url | 无论是同源请求还是非同源请求,都发送完整的 URL(移除参数信息之后)作为引用地址。 |
更详细的文档:Referrer-Policy
设置以上代码后就可以成功访问到图片链接啦(嘿嘿,真简单)。
就在我以为问题完美解决的时候,项目中的微信支付出现了“商家参数有误,请联系商家解决”,通过微信支付文档可以知道,是因为调起h5支付的referer为空导致的,如图:
所以不能通过全局meta来访问防盗链图片,我们可以设置单个标签的referrer来实现:
<img referrer="no-referrer|origin|unsafe-url" src="{{src}}"/>
需要注意的是,这个方法不支持gif图片,只能显示静态图片。
方法二:
代理图片,使用images.weserv.nl方案,这样就可以优雅的访问图片啦。
getImage(url){
// 把现在的图片连接传进来,返回一个不受限制的路径
if(url !== undefined){
return url.replace(/^(http)[s]*(\:\/\/)/,'https://images.weserv.nl/?url=');
}
}
Images.weserv.nl,是一个利用cloudflare的CDN,可缓存、直链Google、Drive、OneDrive等图片的网站,同时,发布了这样的源码,自己能够创立,用于图片存储等。支持IPv6。
结语
大家端午快乐!