學習 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 攜帶信息的完整度,可以總結成一個表格,可以按照自己的需求配置不同的策略:

E6J8dl

瀏覽器默認的策略

Q5V3Cb

設置 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 信息能夠通過日誌抓取到完整鏈路,也就意味着你的訪問路徑和來源是沒有任何隱藏,這樣可能會對隱私及網站的安全性帶來一定的危害。

參考資料

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/HfOstfIdWsjNargulh5q5g