han's bolg - 年糕記

认识http referrer

Referer 是一个请求头参数,提供访问来源的信息

前端通过document.referrer来获取,document.referrer 只读。

发送 referrer 的场景:

  • 用户点击网页上的链接
  • 用户发送表单
  • 网页加载静态资源,比如加载图片、脚本、样式

referrer 值为空的场景:

有时候,我们从请求头里看不到 referrer 值,document.referrer=''。通常是在以下场景中会这样:

  • 直接在浏览器中输入地址
  • 使用 location.reload()刷新(location.href 或者 location.replace()刷新有信息)
  • 在微信对话框中,点击进入微信自身浏览器
  • 扫码进入微信或 QQ 的浏览器

简单说,就是在浏览器的新 tab 第一个打开页面的时候。

Referrer Policy

Referrer 有以下 8 种值,来控制是否显示 referrer,以及显示什么内容。

(1)no-referrer

不发送 Referer 字段。

(2)no-referrer-when-downgrade (大部分浏览器的默认行为)

如果从 HTTPS 网址链接到 HTTP 网址,不发送 Referer 字段,其他情况发送(包括 HTTP 网址链接到 HTTP 网址)。

(3)same-origin

链接到同源网址(协议+域名+端口 都相同)时发送,否则不发送。注意,https://foo.com 链接到http://foo.com也属于跨域。

(4)origin

Referer 字段一律只发送源信息(协议+域名+端口),不管是否跨域。

(5)strict-origin

如果从 HTTPS 网址链接到 HTTP 网址,不发送 Referer 字段,其他情况只发送源信息。

(6)origin-when-cross-origin

同源时,发送完整的 Referer 字段,跨域时发送源信息。

(7)strict-origin-when-cross-origin (chrome的默认行为)

同源时,发送完整的 Referer 字段;跨域时,如果 HTTPS 网址链接到 HTTP 网址,不发送 Referer 字段,否则发送源信息。

(8)unsafe-url

Referer 字段包含源信息、路径和查询字符串,不包含锚点、用户名和密码。

Referrer 策略可以通过以下方法声明:

  1. 通过隐式继承
  2. 通过 meta 标签,name 为 referrer
  3. 通过 http 请求头中的 Referrer-Policy 字段
  4. 通过<a><area><img><iframe><link>元素的referrerpolicy属性。
  5. 通过<a><area> <link>元素的rel=noreferrer属性

优先级依次加重

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="referrer" content="unsafe-url" />
<title>Document</title>
</head>
<body>
<a
referrerpolicy="origin"
href="https://f2estatic.youdao.com/handw/testReferrer2"
>跳转链接origin</a
>
<a
referrerpolicy="origin-when-cross-origin"
rel="noreferrer"
href="https://f2estatic.youdao.com/handw/testReferrer2"
>跳转链接noreferrer</a
>

<a
referrerpolicy="origin-when-cross-origin"
rel="no-referrer"
href="javascript:void(0)"
onclick="handleClick()"
>跳转链接location.href</a
>

<script>
function handleClick() {
window.testsourceurl = window.location.href
location.href = 'https://f2estatic.youdao.com/handw/testReferrer2'
}
</script>

<img
src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1604857952905&di=b33cd45427b465a7abf938b7bf9ad800&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201503%2F07%2F20150307213740_PhyQE.png"
alt=""
/>
</body>
</html>

  • 第一个链接跳转后的 html 文件,请求头中的Referrer Policy: origin
  • 第二个链接跳转后的 html 文件,请求头中的Referrer Policy: no-referrer(rel:noreferrer 的优先级高于 referrerpolicy)
  • 除了特别指明 Referrer policy 的内容,页面中的 Referrer policy 取决于 meta 标签
  • 第三个链接的跳转,用了 location.href,所以请求头中的Referrer Policy: unsafe-url
  • 图片https://ydschool-video.nosdn.127.net/1597307153289title.png请求头中的Referrer Policy: unsafe-url

参考文档