简介

在Chrome 85中,有个很重要的变化:将Referrer-Policy默认值从no-referrer-when-downgrade改为strict-origin-when-cross-origin,它会对埋点、网站分析等功能造成影响。本文会详细介绍这个变化,文章分为以下几个部分:前置知识、变化原因、影响范围、处理方案。

前置知识

Origin:HTTP请求头部字段,指示了请求来自于哪个站点。该字段仅指示服务器名称,并不包含任何路径信息。

Origin: ""
Origin: <scheme> "://" <host> [ ":" <port> ]

Referer:HTTP请求头部字段,用来表示发出该请求的页面地址。和Origin不同的是,它包含路径信息。常被人津津乐道的是,它拼写错了,正确的拼法是Referrer。

Referer: <url>

Referrer-PolicyHTTP请求头部字段顾名思义,它用来控制应该在Referer中暴露多少信息,同样顾名思义,它纠正了Referer的错误拼写。Referrer-Policy可以为以下取值之一:

Referrer-Policy: no-referrer // 无referer字段
Referrer-Policy: no-referrer-when-downgrade // 当从https网站发起http请求时, 无referer字段,它也是Chrome 85之前的默认值
Referrer-Policy: origin // 只发送origin信息
Referrer-Policy: origin-when-cross-origin // 当跨域时,referer字段只包含origin信息,否则是完整路径
Referrer-Policy: same-origin // 跨域时没有referer字段,否则会发送完整referer信息
Referrer-Policy: strict-origin // 降级的情况下不会发送 (HTTPS->HTTP)
Referrer-Policy: strict-origin-when-cross-origin // 对于同源的请求,会发送完整的URL作为引用地址;在同等安全级别的情况下,发送文件的源作为引用地址(HTTPS->HTTPS);在降级的情况下不发送此首部 (HTTPS->HTTP)
Referrer-Policy: unsafe-url // 无论是同源请求还是非同源请求,都发送完整的 URL(移除参数信息之后)作为引用地址。

各个取值的差别,在下图中会更一目了然:

image.png

Referrer-Policy可以用如下方式来设置:


<meta name="referrer" content="origin">


<a href="http://example.com" referrerpolicy="origin">


fetch('//example.com', {
  referrer: "https://www.atatech.org/"
});

变化原因

这项变化是为了保护用户的私密性。在以前,第三方站点默认可以获取完整的网站url,包活源、路径、请求参数等。比如我的雨雀个人空间首页:https://www.yuque.com/akiragg,其中包含了我的用户id。更有甚者,部分网站会在页面url中加上token,以传递给回调地址,这会带来巨大的安全隐患。


下图可以清晰地展示私密信息泄漏的等级:

image.png

Referrer-Policy默认值变为strict-origin-when-cross-origin之后,默认只会把origin传递给第三方站点,隐藏了很多信息。


目前为止,除了Chrome以外,其他浏览器也在做相应的升级,如下:


浏览器默认 Referrer-Policy / 行为
Chrome

85版本开始切换到 strict-origin-when-cross-origin

Firefox
  • 目前是 no-referrer-when-downgrade
  • 正在考虑切换到 strict-origin-when-cross-origin
  • 私密浏览模式下,已经使用strict-origin-when-cross-origin
Edge

80版本开始切换到 strict-origin-when-cross-origin

Safari类似于 strict-origin-when-cross-origin. 详见链接 Preventing Tracking Prevention Tracking


影响范围

服务端埋点和分析功能依赖于网站url的完整路径。如Google Analytics,以及阿里的埋点工具aplus。

以我支持的某业务网站为例,由于网站没有设置Referrer-Policy,使用了默认值strict-origin-when-cross-origin,所以其向aplus服务端发起的GET请求中,Referer-Policy字段为strict-origin-when-cross-origin,Referer字段为​https://e-bnp.taobao.com/​,没有路径信息。


image.png


image.png


在iframe中,访问document.referrer会返回父页面的url,它也同样受这个policy的制约。

处理方案

  1. 显式设置一个Referrer-Policy,比如 no-referrer-when-downgrade
  2. 渐进增强。

Referrer-Policy是有一个优先级顺序的:

    1. Element-level policy
    2. Page-level policy
    3. Browser default

元素级别的策略优先级最高,页面级别的次之,浏览器默认值最低。所以,可以先设置一个较严格的页面级策略,再对某些资源做渐进增强,如下:

<!-- 页面配置: 较严格 -->
<meta name="referrer" content="strict-origin-when-cross-origin" />

<!-- img配置: 允许跨域时传递完整url -->
<img src="…" referrerpolicy="no-referrer-when-downgrade" />

<!-- 脚本配置: 允许跨域时传递完整url -->
<script>
    fetch(url, {referrerPolicy: 'no-referrer-when-downgrade'});
</script>
  1. 显式在请求参数中带上路径及请求参数信息。如阿里云ARMS的做法:

image.png

更多相关资料及解决方案,请查看链接

参考文献

https://developers.google.com/web/updates/2020/07/referrer-policy-new-chrome-default

https://web.dev/referrer-best-practices/

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Referrer-Policy

https://www.maxlist.xyz/2020/08/03/chrome-85-referer-policy/

https://developer.mozilla.org/zh-CN/docs/Web/API/Document/referrer