认识http referrer

836 阅读2分钟

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属性

优先级依次加重

例如:

<!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://example.com/testReferrer2"
      >跳转链接origin</a
    >
    <a
      referrerpolicy="origin-when-cross-origin"
      rel="noreferrer"
      href="https://example.com/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://example.com/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://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请求头中的Referrer Policy: unsafe-url

参考文档