document.referrer实践

引荐来源 (Referer) 和引荐来源政策 (Referrer-Policy) 最佳实践

2023.2.6 星期一

背景:有些情况无法获得document.referrer, 或者只能获取的origin。

基础介绍

概述
引荐来源和引荐来源政策 101
有哪些可用的政策,它们之间有何不同?
浏览器中的默认引荐来源政策
设置您的引荐来源政策:最佳实践
如何查看引荐来源政策?
您应该为您的网站设置哪种政策?
为什么要”显式”?
为什么要用strict-origin-when-cross-origin(或更严格的政策)?
如果strict-origin-when-cross-origin(或更严格的政策)不适用于您所有的用例怎么办?
示例:元素级政策
示例:请求级政策
您还应该考虑什么?
使用传入请求中的引荐来源:最佳实践
如果您的网站功能使用传入请求的引荐来源 URL 怎么办?
跨站请求伪造 (CSRF) 保护
日志记录
付款
结论
资源

一、Referer 的含义
二、Referer 的发生场景
浏览器向服务器请求资源的时候,Referer字段的逻辑是这样的,用户在地址栏输入网址,或者选中浏览器书签,就不发送Referer字段。

主要是以下三种场景,会发送Referer字段。
(1)用户点击网页上的链接。
(2)用户发送表单。
(3)网页加载静态资源,比如加载图片、脚本、样式。
三、Referer 的作用
四、rel属性
由于上一节的原因,浏览器提供一系列手段,允许改变默认的Referer行为。

五、Referrer Policy 的值

Referrer Policy 可以设定8个值。
(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字段包含源信息、路径和查询字符串,不包含锚点、用户名和密码。

六、Referrer Policy 的用法

(1)HTTP 头信息
服务器发送网页的时候,通过 HTTP 头信息的Referrer-Policy告诉浏览器。
Referrer-Policy: origin
(2)<meta>标签
也可以使用<meta>标签,在网页头部设置。
<meta name="referrer" content="origin">
(3)referrerpolicy属性
<a>、<area>、<img>、<iframe><link>标签,可以设置referrerpolicy 属性。
<a href="..." referrerpolicy="origin" target="_blank">xxx</a>

简单结论

有不同浏览器及政策,包括跳转方式的不同。

最后,一个简单的结论是:如果你需要通过 document.referrer 采集页面访问来源,最好不要使用 JS 跳转或打开新窗口,也不要使用 meta 跳转。

无法获取场景

二、哪些场景下无法获得上一页referrer信息
1) 直接在浏览器地址栏中输入地址;
2) 使用location.reload()刷新(location.href或者location.replace()刷新有信息);
3) 在微信对话框中,点击链接进入微信自身的浏览器;
4) 扫码进入QQ或者微信的浏览器;
5) 直接新窗口打开一个页面; 2017.8.3更新 新版本Chrome测试,新窗口页面依然有document.referrer
6) 从https的网站直接进入一个http协议的网站(Chrome下亲测);
7) a标签设置rel=”noreferrer”(兼容IE7+);
8) meta标签来控制不让浏览器发送referer
<meta content="never" name="referrer">

  • 修改Location对象进行页面导航
  • window.open方式打开新窗口
  • 鼠标拖拽打开新窗口
  • 点击Flash内部链接
  • HTTPS跳转到HTTP

防盗链

只有当用户在上一个页面点击链接到达当前页面,document.referrer才会有值当用户输入这一页的网址、通过response.redirect、用了ssl这些情况referrer都会为空。
另外,其必须通过http协议使用。否则不能得到返回值,即值为空。
项目中引用了外链图片, 在本地页面里用img标签访问页面图片返回403 forbidden。
而浏览器可以直接打开. 应该好像是他们的服务器做了处理(防盗链)

由于可以直接从浏览器打开,就简单设置了个 meta标签

1
<meta name="referrer" content="no-referrer" />

knowledge is no pay,reward is kindness
0%