前言
最近排查一个问题,页面上有几个三方(跨域)接口,HTTP请求头没有带referer信息,要求前端排查原因。
web页面是通过服务端接口返回的,服务端是nodeJS/Koa框架。
什么是referer?
Referer是HTTP请求头中的一个字段,用于指示当前请求的来源页面URL.当用户从一个页面点击链接访问另一个页面时,浏览器会自动在请求头添加这个字段。
referer有什么作用?
referer的本质作用是“告诉服务端,我从哪里来”。
主要用于统计、业务判断等。
但不安全、不可靠,受浏览器策略严格控制,
只能作为辅助信息。
从浏览器端排查
为什么第一判断是从浏览器排查呢?
因为三方请求是从当前页面发出的,也不会经过当前页面所在服务端。
1. 普通页面跳转/资源加载,浏览器默认会自动携带Referer
<a href="https://example.com">link</a>
<img src="https://example.com/a.png" />
<script src="https://example.com/a.js"></script>
2. 可以使用 Fetch API 提供的专用选项来设置
fetch('https://example.com/api', { // 只能设置为当前源或空字符串
referrer: 'https://www.lenovo.com/', // 必须是同源URL // 指定引用策略
referrerPolicy: 'strict-origin-when-cross-origin' // 其他合法值: 'no-referrer', 'no- referrer-when-downgrade', // 'origin', 'origin-when-cross-origin', 'same-origin', 'strict-origin'
});
- no-referer 永远不发送
- origin 只发送域名
- same-origin 仅同源
- strict-origin-when-cross-origin
- 当请求目标与当前页面同源,发送完整URL作为Referer(包含路径、查询参数等)
- 当请求目标与当前页面不同源时:只发送origin,不包含路径和查询参数
- unsafe-url 完全url
3. 使用HTML meta标签
<meta name="referrer" content="strict-origin-when-cross-origin">
了解了以上知识点,网页meta标签没有任何设置,其次接口请求也没有设置。
网页添加上如上配置之后,HTTP的request请求头中还是没有带referer。
排查服务端
服务端也没有显示设置,这就奇怪了!
于是尝试在服务端直接设置referrerPolicy:
// 安全头
app.use(
// 修改 Referrer-Policy,允许在同等安全级别下发送 Referrer (如 https -> https)
referrerPolicy: { policy: "no-referrer-when-downgrade" },
}),
)
让我们了解一下
no-referrer-when-downgrade 与 strict-origin-when-cross-origin 的区别:
| 情况 | no-referrer-when-downgrade | strict-origin-when-cross-origin |
|---|---|---|
| HTTPS → HTTPS (同源) | 完整 URL | 完整 URL |
| HTTPS → HTTPS (跨源) | 完整 URL | 仅源 (origin) |
| HTTPS → HTTP | 无 Referer | 无 Referer |
| HTTP → 任何 | 完整 URL | 完整 URL (同源) / 仅源 (跨源) |
一测试,居然HTTP Request都带上了referer!!!
这是为什么呢?
原因如下: 该页面从服务端接口返回的。页面HTTP的response中携带了了Referrer policy: no-referer。如图所示:
当服务器在 HTTP 响应中设置了 Referrer-Policy 头部时,它会覆盖浏览器的默认行为,成为该页面及其资源请求的权威策略
总结
- 学习了什么是referer字段和referer字段的作用
- HTTP 响应头中的
Referrer-Policy拥有最高优先级