由最近 基于vue的知乎日报单页应用 引发的问题 以及问题解决历程
通过 知乎日报API 基于vue做一个知乎日报的单页应用,在获取图片时存在一个图片盗链问题,图片无法加载 提示 403 错误,
最终解决方法 添加meta标签
<meta name="referrer" content="never">
以下两点为个人的解决问题的过程, 和该meta标签的详细介绍, 不感兴趣的小伙伴可以忽略
1、解决问题的过程记录
遇到问题不要慌,要记住充分利用网络, 利用搜索引擎 找找前辈们遇到的同样的坑,看他们怎么填,一来可以快捷的解决问题,二来可以快速学习前辈的解决思路
我先找到了 知乎日报API 项目下的 Issues 果然有人遇到同样问题,一个是纯前端的解决方法(通过跳板链接, 也是我初期采用的), 一个是基于后端的方法(该方法说明了图片盗链问题的本质, 原理 “原理是request的headers里有个Referer”)
采用方法一 就要在每一个引用图片文件的地方添加跳板链接,很麻烦,
采用方法二 我的项目属于纯前端的 通过API获取信息 然后展示的一个过程,再写一个后台麻烦,
综上, 可不可以找一个通过前端来解决的方式呢,被我找到了,在 这里
找到解决方案是目的,但绝不是问题的终点
2、使用 Referer Meta 标签控制 referer
以下内容为转载内容 可以移步 原文地址
这里描述了一个关于 http 协议中 referer 的 metadata 参数的提议,使用这个 metadata 参数,html 文档可以控制 http 请求中的 referer ,比如是否发送 referer、只发送 hostname 还是发送完整的 referer 等。虽然有一些方法可以控制 referer ,比如 flash,以及一些 js 的 tricks,但是本文中描述的是另外一番景象。
使用场景
在某些情况下,出于一些原因,网站想要控制页面发送给 server 的 referer 信息的情况下,可以使用这一 referer metadata 参数。
隐私
社交网站一般都会有用户个人页面,这些页面中用户都有可能添加一些外网的链接,而社交网站有可能不希望在用户点击了这些链接的时候,泄露用户页面的 URL ,因为这些 URL 中可能包含一些敏感信息。当然,有些社交网站可能只想在 referer 中提供一个 hostname,而不是完整的 URL 信息。
安全
有些使用了 https 的网站,可能在 URL 中使用一个参数(sid 等)来作为用户身份凭证,而又需要引入其他 https 网站的资源,这种情况下,网站肯定不希望泄露用户的身份凭证信息。
Object-Capability Discipline
有些网站遵循Object-Capability Discipline,而 referer 刚好与这一策略相悖,所以,网站能够控制 refeer 将对 Object-Capability Discipline 很有利。
技术细节
referer 的 metedata 参数可以设置为以下几种类型的值:
never always origin default
如果在文档中插入 meta 标签,并且 name 属性的值为 referer,浏览器客户端将按照如下步骤处理这个标签:
1.如果 meta 标签中没有 content 属性,则终止下面所有操作 2.将 content 的值复制给 referrer-policy ,并转换为小写 3.检查 content 的值是否为上面 list 中的一个,如果不是,则将值置为 default
上述步骤之后,浏览器后续发起 http 请求的时候,会按照 content 的值,做出如下反应(下面 referer-policy 的值即 meta 标签中 content 的值):
1.如果 referer-policy 的值为never:删除 http head 中的 referer; 2.如果 referer-policy 的值为default:如果当前页面使用的是 https 协议,而正要加载的资源使用的是普通的 http 协议,则将 http header 中的 referer 置为空; 3.如果 referer-policy 的值为 origin:只发送 origin 部分; 4.如果 referer-policy 的值为 always:不改变http header 中的 referer 的值,注意:这种情况下,如果当前页面使用了 https 协议,而要加载的资源使用的是 http 协议,加载资源的请求头中也会携带 referer。
例子
如果页面中包含了如下 meta 标签,所有从当前页面中发起的请求将不会携带 referer:
<meta name="referrer" content="never">
如果页面中包含了如下 meta 标签,则从当前页面中发起的 http请求将只携带 origin 部分(注:根据原文中的语境,我理解这里的 origin 是包含了 schema 和 hostname 的部分 url,不包含 path 等后面的其他 url 部分),而不是完整的 URL :
<meta name="referrer" content="origin">