原文地址:https://segmentfault.com/a/1190000024540592


Referer(引荐者)请求头

referer 与 origin的区别?

  1. origin 是协议、域名;referer可以根据携带路径和参数

referer 是什么?什么时候携带?什么时候不携带?

referrer是HTTP请求header的报文头,用于指明当前流量的来源参考页面。通过这个信息,我们可以知道访客是怎么来到当前页面的。这对于Web Analytics非常重要,可以用于分析不同渠道流量分布、用户搜索的关键词等。
Referer 请求头包含了当前请求页面的来源页面的地址,即表示当前页面是通过此来源页面里的链接进入的。服务端一般使用 Referer 请求头识别访问来源,可能会以此进行统计分析、日志记录以及缓存优化等。

referer的两种形式(个人认为)

  1. 网页的referer,即请求html文件接口请求头携带的Referer;可以通过document.referrer 获取;

    1.1 从a标签跳转的页面,从百度搜索页跳转的页面(百度自家网站,即同域名跳转),刷新,document.referrer 不变!

    1.2 从百度搜索页跳转的页面(其他网站的页面),刷新,document.referrer变为空!! 因为涉及到百度引导流量的统计,所以这个再次刷新后document.referrer 变为空,感觉是合理的,但不知道是怎么实现的。??

  2. 其他请求静态资源或是交互api请求头的Referer

常见不携带的情况:

  1. 来源页面采用的协议为表示本地文件的 "file" 或者 "data" URI;
  2. 当前请求页面采用的是非安全协议,而来源页面采用的是安全协议(HTTPS);即从https到http;与referrer policy的默认值一个意思。
  3. 用户在地址栏输入网址,或者选中浏览器书签,也不发送Referer字段。
  4. 使用http重定向

控制referer的方式

meta方式

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

html 标签方式

  1. 通过referrerpolicy在内容属性aareaimgiframelink,或script元素

1.1 例如

<a href="http://example.com" referrerpolicy="origin">
  1. 通过元素rel属性控制aareaform
<a href="..." rel="noreferrer" target="_blank">xxx</a>

服务器发送网页的时候,通过 HTTP 头信息的Referrer-Policy告诉浏览器。

像这样:

Referrer-Policy: origin

Referrer policy 控制Referer内容

referrer policy 各值的含义

(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

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

(8)unsafe-url

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

遗留未知内容

解决的问题

如何让浏览器在访问链接时不要带上referer

  1. 基于HTML标准,可以在a标签内使用rel="noreferrer"来达到这一目的。目前大部分基于Webkit的浏览器已经支持。Opera并没有提供可以实现不发送referrer的方法,Firefox也不支持。
  2. 提供跨浏览器支持的更好的办法是使用一个第三方的库noreferrer.js,它可以自动识别浏览器并选择最优方案。实现方式利用google url中转,国内环境不行。
  3. 跨浏览器解决方案,做一个自己网站的中转页。例如百度,搜索结果页跳转都会经过一个中转页。

百度中转页做了哪些事

  1. 从referer剥离参数wd,保护用户隐私
  2. 新窗口打开中间页面
  3. 验证点击真实性

百度在这个中间页调用了window.opener.bds.pdc.sendLinkLog(); 即在百度搜索结果页调用sendLinkLog()统计方法,验证是不是真实点击,因为如果不是从搜索结果页进入,是不存在这个方法的。虽然不能杜绝虚假模拟点击,这很大程度上过滤掉了许多爬虫和低级的虚假点击,为点击数据真实性加了“双保险”。

  1. 剥离Opener,保障安全
  2. 跳转到目标页面

参考内容

  1. https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Referer
  2. http://www.ruanyifeng.com/blog/2019/06/http-referer.html
  3. https://w3c.github.io/webappsec-referrer-policy/
  4. https://www.sohu.com/a/271128047_100258515
  5. http://www.imaiko.com/baidu-thunder-math-bug-test.html