背景
近期有一个需求,当用户点击某个按钮时,系统会发起一个 HTTP 请求,后端需要根据 Referer 头字段记录用户在哪个页面点击的按钮。在本地和线上环境进行了测试时,发现两者在 Referer 头字段的处理上存在显著差异。
问题描述
在本地和线上环境发起相同的 HTTP 请求时,Referer 头字段的内容表现出明显的差异:
-
本地环境:
Referer头字段仅包含协议、域名和端口号:Referer: http://localhost:8080/ -
线上环境:
Referer头字段包含完整的 URL 路径信息:Referer: https://myapp.production.com/page1/action
进一步检查发现,本地环境中发起的请求,来源 URL 和目标 URL 不一致。例如:
- 本地环境的来源 URL:
http://localhost:8080/ - 本地环境的目标 URL:
https://api.staging.com/endpoint
这种跨域请求引发了浏览器的跨域安全策略,导致 Referer 头字段处理存在差异。
原因分析
通过阅读 MDN Referrer-Policy 文档 及其他资料,我发现主要有两个原因导致这种差异:跨域请求的处理方式和浏览器的 Referrer-Policy 默认设置。
-
跨域请求的不同处理: 在本地开发环境中,发起的请求常常是跨域请求。例如:
- 本地的来源 URL:
http://localhost:8080/ - 本地的目标 URL:
https://api.staging.com/endpoint
浏览器对于跨域请求采取严格的安全策略,通常会简化
Referer头字段内容,以减少潜在的隐私泄露风险。结果,本地环境中Referer头字段仅包含基本信息:协议、域名和端口号。 - 本地的来源 URL:
-
浏览器的
Referrer-Policy默认设置:浏览器的
Referrer-Policy控制着发起请求时如何发送Referer头字段。默认情况下,Referrer-Policy设置为strict-origin-when-cross-origin,其行为如下:- 同源请求:发送完整的
Referer,包括协议、域名、端口号、路径和查询字符串。 - 跨源请求:
- 相同的安全级别(如 HTTPS 到 HTTPS):仅发送来源,包含协议、域名和端口号,不包括路径和查询字符串。
- 降低安全级别(如 HTTPS 到 HTTP):不发送
Referer头字段。
该策略旨在保护用户隐私,在跨域请求时减少敏感信息的暴露。
- 同源请求:发送完整的
结果
以下是导致本地和线上环境中 Referer 头字段处理差异的原因总结:
-
跨域请求的简化处理:在本地开发环境中,跨域请求导致
Referer头字段被浏览器简化,只包含协议、域名和端口号。 -
同源请求的完整信息:在生产环境中,请求大多数是同源请求,因此浏览器发送完整的
Referer头字段,包括路径和查询字符串。 -
默认的
Referrer-Policy设置:按照strict-origin-when-cross-origin策略处理跨域请求,确保隐私和安全。
结论
希望我的经验分享对大家有所帮助。如果你在开发过程中遇到了类似的问题,可以查阅相关文档,合理设置 BASE_URL 和 Referrer-Policy,以确保前端请求的一致性。
感谢大家的阅读,如果有任何问题或建议,欢迎在评论区交流分享!