學習 HTTP Referer
背景
HTTP 中 Referer 字段在工作中或許並不會吸引你的注意,隱藏在 Network 的請求之下,但是卻有着非常重要的作用。平常你一定會遇到一些問題需要去排查,假如這個問題在你排查完全部代碼後,依然沒有解決,這個時候你會怎麼辦?此時我們就需要將排查問題的角度轉換一下,切換到 HTTP 協議上。
最近工作當中也碰到了與此相關的一些問題,藉此機會也同時做個記錄和總結。HTTP 協議整體包含內容非常多,本次我們只把其中的 Referer 字段拿出來和大家詳細說一下。
HTTP Referer
Referer 是什麼?
HTTP Referer 是 HTTP 表頭的一個字段,用來表示當前網頁是來源於哪裏,採用的格式是 URL。我們通過這個 HTTP Referer,可以查到訪客的來源。
可以通過 Network 面板看到,頁面訪問及資源請求的 Request Headers 請求頭信息裏有一個 Referer 字段,用來標記來源的 URL。
有同學可能會注意到 Referer “似乎” 拼寫有誤,應該是 “Referrer" 纔對,這其實是個歷史原因,在早期 HTTP 規範當中就存在的拼寫錯誤,後面爲了向下兼容,所以將錯就錯。
拼寫錯誤只有 Request Headers 的 “Referer”,在其他地方比如 General Headers、 JavaScript 及 DOM 上,都是正確的拼寫。
General Headers:
// javascript
document.referrer
// DOM
<a target="_blank" href="https://edu.zcygov.cn/live" referrerpolicy="no-referrer">查看鏈接</a>
到此大家應該對 Referer 有了一個大概的瞭解,那麼 Referer 字段在什麼條件下會展示,以及如何去控制 Referer 返回的具體內容呢?答案就在 Referrer-Policy 當中,下面就帶大家詳細講一下 Referrer-Policy 策略。
Referrer-Policy 策略
有哪些策略?
Referrer-Policy: no-referrer
顧名思義,這個策略表示不發送 Referer 信息。
工作中實際使用的場景:
在雙品牌 “樂彩雲” 推廣中爲降低雙域名跳轉改造成本,運維層面在 Nginx 添加了一個規則,若訪問鏈接(例如 news.zcygov.cn)的 Referer 包含 lecaiyun.com 域名,則會強制將訪問鏈接的域名變更爲 lecaiyun.com ,實現鏈接跳轉統一。
若部分域名不需要走這一套邏輯,不攜帶 Referer 頭信息,則需要指定 Referrer-Policy 策略爲 no-referrer 。
Referrer-Policy: no-referrer-when-downgrade
如果從 HTTPS 網址鏈接到 HTTP 網址,不發送 Referer 字段,其他情況發送(包括 HTTP 網址鏈接到 HTTP 網址)。
此規則原先是大多數瀏覽器的默認策略,現在隨着隱私安全性的要求變高之後,瀏覽器將默認規則變更成了 strict-origin-when-cross-origin。
Referrer-Policy: origin
Referer 字段一律只發送源信息(協議 + 域名 + 端口),不管是否跨域。
Referrer-Policy: origin-when-cross-origin
同源時,發送完整的 Referer 字段,跨域時發送源信息。
Referrer-Policy: same-origin
鏈接到同源網址(協議 + 域名 + 端口 都相同)時發送,否則不發送。注意,https://foo.com 鏈接到 http://foo.com 也屬於跨域,因爲兩者的協議不同。
Referrer-Policy: strict-origin
如果從 HTTPS 網址鏈接到 HTTP 網址,不發送 Referer 字段,其他情況只發送源信息。
Referrer-Policy: strict-origin-when-cross-origin
同源時,發送完整的 Referer 字段;跨域時,如果 HTTPS 網址鏈接到 HTTP 網址,不發送 Referer 字段,否則發送源信息。
Referrer-Policy: unsafe-url
Referer 字段包含源信息、路徑和查詢字符串,不包含錨點、用戶名和密碼。
針對以上策略,可以根據策略及 Referer 攜帶信息的完整度,可以總結成一個表格,可以按照自己的需求配置不同的策略:
瀏覽器默認的策略
設置 Policy 的方法
當我們需要變更 Referer 策略的時候,瀏覽器本身以及 W3C 規範都給我們提供了路徑,有以下幾種方式可以操作:
rel 屬性
a、area 標籤均支持 rel 屬性,最常見的就是在 a 標籤中對單個鏈接設置 rel="noreferrer"
<a href="xxx" rel="noreferrer" target="_blank">新地址</a>
設置之後,新開的網頁請求頭中,將不再攜帶來源頁面的 Referer 信息。
標籤
在 HTML 的 head 標籤內,可以新增 meta 標籤,設置整個網頁的 Referer Policy 策略。
<meta >
Headers 請求頭
更改 HTTP 頭信息中的 Referer-Policy 值即可。比如你使用的是 Nginx,則可以設置 add_headers 設置請求頭。
add_header Referrer-Policy "no-referrer";
設置完請求頭,最終體現在瀏覽器 Headers 裏字段是:
Referrer-Policy: no-referrer
referrerpolicy 屬性
這個目前看還是實驗性功能,並且在 IE 瀏覽器上也是完全不支持的。
<a href="xxx" referrerpolicy="no-referrer" target="_blank">新地址</a>
支持的標籤:a、area、img、iframe、link
優先級
以上幾種設置方式,有頁面級和元素級,當這兩者都存在時,優先級按以下方式進行生效:
1、元素級政策
2、頁面級政策
3、瀏覽器默認
舉例:
<meta >
<a href="https://foo.com" rel="no-referrer" target="_blank">地址一</a>
<a href="https://bar.com" target="_blank">地址二</a>
頁面中地址一,則優先按元素級策略,走 no-referrer,而頁面中其他元素(包括但不限於 a 標籤)則按 meta 頁面級策略執行
作用及使用場景
以下列舉了幾個比較常見的作用及使用場景:
(1)防盜鏈
以 CDN 加速爲例,一般都提供了防盜鏈配置,其內部實現原理是按照 Referer 來源來判斷是否在配置的白名單或者黑名單中,來決定資源能否可被訪問。
圖片來自 [阿里雲 CDN 的防盜鏈配置] https://help.aliyun.com/document_detail/27134.html
(2)埋點分析
埋點分析有一種情況是用於追溯用戶的完整訪問路徑,這個時候可以依賴的就是 HTTP Referer,可以通過 Referer 來源逐步分析用戶的來源網址和整體訪問鏈路。
(3)錯誤排查(接口日誌)
排查接口請求報錯時,一般會關注日誌系統,而日誌系統裏如果沒有對於接口訪問來源的字段,那麼想快速精確找到接口訪問的頁面是比較困難的。這時候 Referer 就提供了一個比較好的幫助,可以看到接口的請求來源。
(4)用戶隱私保護
爲什麼各瀏覽器廠商都升級了 Policy 默認策略?
目的其實是爲了保護用戶隱私,過於完整的 Referer 信息能夠通過日誌抓取到完整鏈路,也就意味着你的訪問路徑和來源是沒有任何隱藏,這樣可能會對隱私及網站的安全性帶來一定的危害。
參考資料
-
HTTP 來源地址:https://zh.wikipedia.org/wiki/HTTP%E5%8F%83%E7%85%A7%E4%BD%8D%E5%9D%80
-
HTTP Referer 教程:https://www.ruanyifeng.com/blog/2019/06/http-referer.html
-
鏈接類型:https://developer.mozilla.org/zh-CN/docs/Web/HTML/Link_types
-
引薦來源 (Referer) 和引薦來源政策 (Referrer-Policy) 最佳實踐:[https://web.dev/referrer-best-practices/]
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/HfOstfIdWsjNargulh5q5g