缘由
微博图床是网友利用新浪微博上传图片的功能,然后网友将图片的链接进行分享。微博图床的稳定性不用我多介绍,但是由于愈来愈多的网友使用微博做图床,微博官方可能觉得影响服务器或者费用的支出等原因,开始对微博图片添加了防盗链的功能。
新浪微博的图片防盗链:
它的防盗链原理较为简单,只要不是新浪微博的白名单域名请求该图片,服务器会返回一个403的错误码。背后的原理是利用了浏览器的HTTP请求头默认会携带:Referer
属性。而这个属性记录了该请求由哪个域名发送的。所以微博图床直接校验该属性的值,只要不是微博允许的域名访问图片链接,将会不予返回图片。下图是我博客请求一张图片的请求头:
可以看到该请求是由:https://blog.gobyte.cn/post/f9458eff.html发起的,而且这个Referer
属性是浏览器默认携带,既然是默认携带,那肯定有关闭的方法。
解决方法1(不推荐)
在HTML的<head>
标签里添加mate标签,如下:
1 | <meta name="referrer" content="no-referrer" /> |
不推荐该方法的原因是会导致该页面的所有的HTTP请求都不会携带Referer
属性。这会导致部分功能失效,如某些统计信息失效,比如我使用了“不蒜子”的统计功能,会导致失效,所以我推荐方法2.
解决方法2-给图片添加referrerpolicy=“no-referrer”(推荐)
既然不能给所有的HTTP请求添加content="no-referrer"
,那么我们就仅给图片添加。
在img标签有个属性名叫referrerpolicy
,给部分的HTTP请求添加Referer
属性。
原生JavaScript语法:
1 | refStr = imgElt.referrerPolicy; |
referrerPolicy可选值:
1 | "no-referrer":表示HTTP头部信息将不会发送 referrer 。 |
我对这三个值做了3次测试
no-referrer
-测试:
origin
-测试:
unsafe-url
-测试:
三者区别如上面三图所示,符合上面的“referrerPolicy可选值”描述。
所以我们只需要给img标签添加:referrerpolicy="no-referrer"
即可。
但是仅仅不可能每次都去手动添加,所以要么直接修改模板文件,要么写一段JavaScript,让页面加载HTML完成后,再对img标签进行遍历修改,话不多数,以下是我使用jquery完成的代码:
1 | var link = "" ; |
注意:这段JavaScript代码需要放在HTML的底部,所以当HTML第一次加载完图片的时候,不出意外的话console控制台依然会报403错误,因为首次加载图片的时候JavaScript脚本并没有给img添加该属性,所以理所当然的是403。但是如果把JavaScript代码放在页面的顶部,那么会因为图片的img标签晚于JavaScript的执行,导致JavaScript代码找不到img标签会让功能不生效。
操作方法:
找到你的主题的JavaScript代码,我是使用pure主题
我这主题的修改目录:
hexo\pure\layout\_common\script.ejs
里添加上述代码最终修改结果如下:
使用其他主题的同学请自行查找对应的文件修改
当然,如果你知道如何修改Hexo的页面模板,直接在模板里给图片标签加上referrerpolicy="referrerpolicy"
也可以,但是我不知道如何修改。所以我还提供了方法3。
解决方法3-在生成HTML的时候加上referrerpolicy=”referrerpolicy”
注意,因为我是使用Hexo博客程序,该博客是使用markdown编写文章,最后由HEXO程序进行渲染出HTML文件。所以我直接在markdown里标注要需要添加:referrerpolicy="referrerpolicy"
的图片,渲染的时候直接添加该属性。
而Hexo提供了一个自定义函数的功能,操作方法:
在你的Hexo程序目录的“script”文件夹里(如没有自己新建),创建一个文件“myFunction.js”
复制以下JavaScript代码到该文件内
1
2
3
4
5// 给img添加referer policy 标签,解决referer图片防盗链
hexo.extend.tag.register('s', function(args){
const image_url = args[0], alt = args[1];
return `<img src="${image_url}" alt="${alt}" referrerpolicy="no-referrer"></img>`
})在markdown里使用
<% s 图片url alt说明 %>
调用。调用代码示例:1
{% s https://ws4.sinaimg.cn/large/96e311f0gy1g3uyql0zj0g20s60lmn71.gif 删除效果 %}
页面地址为:点我打开效果页面,效果图如下:
该方法适用于偶尔使用微博图床;因为使用了自定义语法的功能,导致markdown编写的时候不能预览图片。而且每次书写自定义代码尤为的不方便,我个人不太建议使用。
总结:
微博这次加了图片防盗链,虽然是很简单的防盗措施,但是也说明了微博对于图片外链的态度,不喜欢网友使用他们的服务器架设图床,所以以后也可能会有更加厉害的防盗链方法也是可能的。
我个人建议各位同学还是架设一个自己的文件存储系统,至少图片不会有丢失、无法访问的风险,目前各大云服务提供商都有免费的套餐,大家可以了解一下。
本篇文章也是个人思考的总结,最后感谢你的耐心阅读。