一個(gè)拼寫(xiě)錯(cuò)誤讓整個(gè)互聯(lián)網(wǎng)一起犯錯(cuò)
在 Web 開(kāi)發(fā)的世界里,有這樣一個(gè)字段——它每天默默地工作著,記錄著用戶(hù)的來(lái)源,保護(hù)著網(wǎng)站的安全,卻因?yàn)橐粋€(gè)歷史性的拼寫(xiě)錯(cuò)誤而成為了程序員們茶余飯后的談資。它就是 HTTP 頭部中的 Referer 字段。
什么是 HTTP Referer
HTTP Referer 是一個(gè)請(qǐng)求頭字段,用于告訴服務(wù)器用戶(hù)是從哪個(gè)頁(yè)面鏈接過(guò)來(lái)的。當(dāng)你從一個(gè)網(wǎng)頁(yè)點(diǎn)擊鏈接跳轉(zhuǎn)到另一個(gè)網(wǎng)頁(yè)時(shí),瀏覽器會(huì)自動(dòng)在新的 HTTP 請(qǐng)求中添加 Referer 頭,其值為上一個(gè)頁(yè)面的 URL。
Referer: https://example.com/page1.html
這告訴服務(wù)器,用戶(hù)是從 https://www.example.com/page1.html 這個(gè)頁(yè)面跳轉(zhuǎn)過(guò)來(lái)的。
圖片
核心作用
1. 流量來(lái)源分析
網(wǎng)站運(yùn)營(yíng)者可以通過(guò)分析 Referer 信息了解:
- 用戶(hù)從哪些網(wǎng)站訪問(wèn)過(guò)來(lái)
- 哪些頁(yè)面是主要的流量入口
- 外部鏈接的效果如何
- 用戶(hù)的瀏覽路徑和行為習(xí)慣
2. 防盜鏈保護(hù)
許多網(wǎng)站利用 Referer 來(lái)防止其他網(wǎng)站直接鏈接自己的圖片、視頻等資源。服務(wù)器可以檢查 Referer 是否來(lái)自允許的域名,如果不是則拒絕請(qǐng)求。
# nginx 圖片防盜鏈配置
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
valid_referers none blocked server_names
*.mysite.com *.mydomain.com;
if ($invalid_referer) {
return 403;
}
}
3. 安全防護(hù)
用于 CSRF 攻擊防護(hù)和惡意請(qǐng)求檢測(cè):
# nginx CSRF 攻擊防護(hù)
location /api {
valid_referers none blocked server_names *.example.com;
if ($invalid_referer) {
return 403;
}
proxy_pass http://backend;
}
這樣就可以檢查請(qǐng)求是否來(lái)自合法域名(*.example.com)。
著名的拼寫(xiě)錯(cuò)誤
圖片
HTTP Referer 存在一個(gè)著名的拼寫(xiě)錯(cuò)誤:正確的英文單詞應(yīng)該是 "Referrer",但在 1995 年制定 HTTP/1.0 規(guī)范時(shí)被誤寫(xiě)為 "Referer"(少了一個(gè) r)。
當(dāng)錯(cuò)誤被發(fā)現(xiàn)時(shí),HTTP 協(xié)議已經(jīng)廣泛部署,為保持向后兼容性,這個(gè)拼寫(xiě)錯(cuò)誤被永久保留:
- HTTP 頭部:使用錯(cuò)誤拼寫(xiě)
Referer
- HTML 屬性:使用正確拼寫(xiě)
referrer
<!-- HTML中使用正確拼寫(xiě) -->
<meta name="referrer" content="origin">
<!-- HTTP頭中使用錯(cuò)誤拼寫(xiě) -->
Referer: https://example.com
Referrer-Policy 策略
為了解決隱私問(wèn)題,W3C 制定了 Referrer Policy 規(guī)范,提供了精細(xì)的控制機(jī)制,現(xiàn)代瀏覽器支持 Referrer-Policy 來(lái)控制 Referer 的發(fā)送行為:
策略值
策略 | 描述 | 使用場(chǎng)景 |
| 不發(fā)送 Referer | 最高隱私保護(hù) |
| HTTPS 到 HTTP 時(shí)不發(fā)送,其他情況正常發(fā)送 | 現(xiàn)代瀏覽器默認(rèn) |
| 只發(fā)送協(xié)議、域名和端口 | 平衡功能和隱私 |
| 同源發(fā)送完整 URL,跨域只發(fā)送域名 | 推薦的默認(rèn)策略 |
| 僅同源請(qǐng)求發(fā)送 Referer | 內(nèi)部分析 |
| 類(lèi)似 origin,但 HTTPS 到 HTTP 時(shí)不發(fā)送: | 較少 |
| 綜合考慮安全性的策略 | 現(xiàn)代瀏覽器默認(rèn) |
| 始終發(fā)送完整 URL | 較少 |
設(shè)置方法
HTTP 響應(yīng)頭:
res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
HTML Meta 標(biāo)簽:
<meta name="referrer" content="strict-origin-when-cross-origin">
元素級(jí)別控制:
<a referrerpolicy="no-referrer">外部鏈接</a>
<img src="image.jpg" referrerpolicy="origin">
rel 屬性相關(guān)值
noreferrer
阻止發(fā)送 Referer 頭:
<a rel="noreferrer">不發(fā)送Referer</a>
noopener
防止新窗口訪問(wèn)原窗口對(duì)象:
<a target="_blank" rel="noopener">安全新窗口</a>
nofollow
告訴搜索引擎不要跟蹤鏈接:
<a rel="nofollow">不被索引的鏈接</a>
組合使用
<a
target="_blank"
rel="noopener noreferrer nofollow">
完全安全的外部鏈接
</a>
總結(jié)
HTTP Referer 雖然只是一個(gè)小小的請(qǐng)求頭,但它承載著 Web 發(fā)展的歷史,見(jiàn)證了互聯(lián)網(wǎng)從功能至上到隱私保護(hù)的轉(zhuǎn)變。那個(gè)著名的拼寫(xiě)錯(cuò)誤也提醒我們,技術(shù)標(biāo)準(zhǔn)的制定需要更加嚴(yán)謹(jǐn)和謹(jǐn)慎。