起由

发布了一版blog到github上。偶然间发现豆瓣页面中书的图片都无法显示了。打开Inspector调查了下,发现请求豆瓣图片的链接返回的都是403 Forbidden。
douban_image_403.png

网上搜索了一下,可能的原因就是豆瓣为了封杀微信小程序在页面上直接请求豆瓣的图片,封杀了图片的外链。

原因

尝试着将豆瓣API返回的图片链接拷贝到浏览器中直接访问,发现可以加载图片,那估计豆瓣是通过检测HTTP Request中的referer Header来实现防盗链。

解决方法

有下面这么几种方法可以来解决该403问题

  1. 架设一个中转服务器,页面请求中转服务器,中转服务器请求豆瓣获取图片后再返回给前端页面。
    • 优点是可以避开Referer Header限制
    • 缺点一是需要假设服务器,成本大
    • 缺点二是貌似豆瓣对请求的IP地址也有限制,请求量大时可能也会被禁。
  2. 通过某些代理网站来获取原始图片,比如要获取图片的原始链接是https://img3.doubanio.com/view/subject/l/public/s29542864.jpg,添加代理网站的信息后,访问链接变为https://images.weserv.nl/?url=img3.doubanio.com/view/subject/l/public/s29542864.jpg,原理和第一种类似,只是中转服务器变为使用第三方了。
    • 优点是方便,快捷,不操心
    • 缺点是依赖于第三方的服务,可用性和稳定性不可控。
  3. 修改网页Html,使得在访问豆瓣图片时,不发送Referer的Header。2017年的时候,W3C制定了一个名为Referrer Policy的规范,可以用来告诉浏览器是否需要发送Referer Header。但非所有浏览器都能支持referrerpolicy这个属性。
    • 好像除了自己可控外, 没什么其它优点。
    • 缺点是并非所有浏览器都能支持referrerpolicy这个属性。在MacOS 10.13.2下试验了几个在用的浏览器,结果如下:
      • 66.0.3359.117版本的Chrome支持
      • 59.0.2版本的Firefox支持该属性
      • 版本为11.0.2 (13604.4.7.1.6)的Safari不支持该属性。即使设置了referrerpolicy=”no-referrer”,还是会发送Referer Header。

方案选取

上面所述的几个方法中:

  • 方法一对于一个托管在Github上,追求简单的Blog来说,太过于沉重了。
  • 方法二是个很好的解决方案,但是自己的Blog就随手写点东西,抱着越简单越好的原则,不想引入任何不必要的第三方服务。
  • 方法三最搓,没有完整的解决问题。但豆瓣页面只是为了记录一下读书记录,没有图片展示也无所谓,自己能看就行。

最终决定采用第三种方法

BLog的豆瓣页面使用的是hexo-generator-douban插件,插件最新维护日期是2016年。因为只是一个自用的不完整的解决方案,没提issue, 就Fork了一份代码到自己的Github,自己改了改,添加了referrerpolicy=”no-referrer”。然后安装github版本到Hexo。

代码修改diff: https://github.com/jibing57/hexo-generator-douban/commit/21f2bc7d2b259c6a9221a5cd3935c222ea0429cc

安装Github代码到本地:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ npm install git+https://github.com/jibing57/hexo-generator-douban.git --save
+ hexo-generator-douban@0.1.2
added 1 package and updated 3 packages in 11.748s
╭─────────────────────────────────────╮
│ │
│ Update available 5.5.1 → 5.8.0 │
│ Run npm i -g npm to update │
│ │
╰─────────────────────────────────────╯
$

本地启动Hexo,在Chrome中就可以正常看到豆瓣的图片了。
douban_image_showed_in_chrome.png

小故事

Header中的referer,其实是referer的拼写错误。参见Wiki HTTP referer

Reference

延伸阅读

留言