HTTP Referer 的最佳实践
2024-09-24
关于 HTTP Referer,阮一峰老师曾经写过一篇很简洁的文章:HTTP Referer 教程 - 阮一峰的网络日志🔗。
这是一个看似简单,内涵却很丰富的概念。可以用于站点分析、安全策略和个性化等场景。
今天之所以打算谈谈这个字段,是因为自己在使用 Google Analytics 或者 Umami 这种站点分析工具的时候,发现有类似 Referrers 这种数据。
借此我们可以分析流量来源及其分布。
1. HTTP Referer 含义
Referer
是 HTTP 请求头字段里的一种,包含当前请求页来源页的地址,注意,是当前页的来源页,另外,这是一个可选标头。
与 POSIX 中 CREAT
的经典错误一样,它是 referrer
的错误拼写,但当时写入 HTTP 规范的时候并没有被发现,于是为了保证前向兼容,只好将错就错。
伴随 Referer
字段,还有两个相关概念。
- Referrer-Policy
- document.referrer
Referrer-Policy
用于控制哪些访问来源信息会放在 Referer
中一起发送。
document.referrer
则是 document
对象中的一个可读字段,可以通过 JavaScript 获取到当前页的来源页。
2. HTTP Referer 使用场景
Referer
请求头的使用通常发生在下列场景中:
- 用户点击链接跳转
- 浏览器请求图片、iframe、脚本或其他资源
而下面两种情况则不会:
- 来源页面采用的协议为本地的文件,如 file:// 或 data://
- 当前请求采用的是非安全协议,而来源页采用的是安全协议(HTTPS)
毫无疑问,Referer
字段会暴露部分隐私。
如上图所示,借助该字段,网站所有者可以在服务端进行流量来源统计。
另外,有些网站不允许图片外链访问,只有自家网页才可以,其内部实现也是借助 Referer
字段,一旦发现请求来自外部站点,直接拒绝。
对于改变默认的 Referer
设置,如果只需要选择是否发送,对于 <a>、<area> 或者 <link> 元素,可将 rel
属性设置为 noreferrer
,例如:
而如果要精确控制哪些来源网页信息可用于当前请求,则需要设置 Referer-Policy
。
Policy 主要分为 8 种情况。参考自:Referrer-Policy - HTTP | MDN🔗。
整个
Referer
🔗 首部会被移除。访问来源信息不随着请求一起发送。在同等安全级别或安全级别提升的情况下(HTTP→HTTP、HTTP→HTTPS、HTTPS→HTTPS),在
Referer
🔗 中发送 来源🔗、路径和查询字符串。而在目标的安全级别下降的情况下(HTTPS→HTTP、HTTPS→file)则不发送Referer
🔗 标头。仅在
Referer
🔗 标头中发送 来源🔗。例如https://example.com/page.html
文档会将https://example.com/
作为引用地址。对于同源的请求,会发送完整的 URL 作为引用地址,但是对于非同源请求仅发送文件的源。
对于 同源的请求🔗 同源的请求发送引用地址,但是对于非同源请求则不发送引用地址信息。
在同等安全级别的情况下,发送文件的源作为引用地址 (HTTPS->HTTPS),但是在降级的情况下不会发送 (HTTPS->HTTP)。
strict-origin-when-cross-origin
🔗(默认值)对于同源的请求,发送来源、路径以及查询字符串。对于在相同安全级别的情况下(HTTPS→HTTPS)的跨源请求,仅发送来源。在目标的安全级别下降的情况下(HTTPS→HTTP)则不发送
Referer
🔗 标头。无论是同源请求还是非同源请求,都发送完整的 URL(移除参数信息之后)作为引用地址。
对于开发者,可以通过 meta
为整个文档设置 Referer
策略。
当然也可以在 <a>、<area>、<img>、<iframe>、<script> 或者 <link> 元素上增加 referrerpolicy
。
3. 最佳实践
参考 web.dev 的 文章🔗,建议明确设置增强隐私保护的策略,例如 strict-origin-when-cross-origin
。
最简单的方法如下:
客户端:
服务端:
原因有四个。
- 兼容性。尽管通常这是个默认值,但不同浏览器或有不同的默认策略,明确设置可以提高兼容性和一致性。
- 安全。如果你的站点使用 HTTPS,那么网站的 URL 就不会泄露给非 HTTPS 的请求,因此免受中间人攻击。
- 增强隐私保护。对于跨域的访问,该 policy 仅共享来源,并不会共享全部网址。
- 内容共享。对于同站点的请求,该 policy 可以将全部信息共享。
4. 总结
由此可见,对于使用者而言,最好的策略往往是灰度的:不完全否定,有条件的信任。
对于产品的设计者,策略的设置则最好划分为几个梯度,允许开发者”渐进增强“。
(完)
参考
- 本文作者:Plantree
- 本文链接:https://plantree.me/blog/2024/http-referer/
- 版权声明:所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
最后更新于: 2024-11-20T09:44:17+08:00