HTTP Referer 教程

阮一峰發表於2019-06-04

HTTP 請求的頭資訊裡面,Referer 是一個常見欄位,提供訪問來源的資訊。

很多開發者知道這個欄位,但是說不清它的具體細節。本文詳細介紹該欄位。

一、Referer 的含義

現實生活中,購買服務或加入會員的時候,往往要求提供資訊:"你從哪裡知道了我們?"

這叫做引薦人(referrer),誰引薦了你?對於公司來說,這是很有用的資訊。

網際網路也是一樣,你不會無緣無故訪問一個網頁,總是有人告訴你,可以去那裡看看。伺服器也想知道,你的"引薦人"是誰?

HTTP 協議在請求(request)的頭資訊裡面,設計了一個Referer欄位,給出"引薦網頁"的 URL。

這個欄位是可選的。客戶端傳送請求的時候,自主決定是否加上該欄位。

很有趣的是,這個欄位的拼寫是錯的。Referer的正確拼寫是Referrer,但是寫入標準的時候,不知為何,沒人發現少了一個字母r。標準定案以後,只能將錯就錯,所有頭資訊的該欄位都一律錯誤拼寫成Referer

二、Referer 的發生場景

瀏覽器向伺服器請求資源的時候,Referer欄位的邏輯是這樣的,使用者在位址列輸入網址,或者選中瀏覽器書籤,就不傳送Referer欄位。

主要是以下三種場景,會傳送Referer欄位。

(1)使用者點選網頁上的連結。

(2)使用者傳送表單。

(3)網頁載入靜態資源,比如載入圖片、指令碼、樣式。


<!-- 載入圖片 -->
<img src="foo.jpg">
<!-- 載入指令碼 -->
<script src="foo.js"></script>
<!-- 載入樣式 -->
<link href="foo.css" rel="stylesheet">

上面這些場景,瀏覽器都會將當前網址作為Referer欄位,放在 HTTP 請求的頭資訊傳送。

瀏覽器的 JavaScript 引擎提供document.referrer屬性,可以檢視當前頁面的引薦來源。注意,這裡採用的是正確拼寫。

三、Referer 的作用

Referer欄位實際上告訴了伺服器,使用者在訪問當前資源之前的位置。這往往可以用來使用者跟蹤。

一個典型的應用是,有些網站不允許圖片外鏈,只有自家的網站才能顯示圖片,外部網站載入圖片就會報錯。它的實現就是基於Referer欄位,如果該欄位的網址是自家網址,就放行。

由於涉及隱私,很多時候不適合傳送Referer欄位。

這裡舉兩個例子,都不適合暴露 URL。一個是功能 URL,即有的 URL 不要登入,可以訪問,就能直接完成密碼重置、郵件退訂等功能。另一個是內網 URL,不希望外部使用者知道內網有這樣的地址。Referer欄位很可能把這些 URL 暴露出去。

此外,還有一種特殊情況,需要定製Referer欄位。比如社交網站上,使用者在對話中提到某個網址。這時,不希望暴露使用者所在的原始網址,但是可以暴露社交網站的域名,讓對方知道,是我貢獻了你的流量。

四、rel屬性

由於上一節的原因,瀏覽器提供一系列手段,允許改變預設的Referer行為。

對於使用者來說,可以改變瀏覽器本身的全域性設定,也可以安裝瀏覽器擴充套件。這裡就不詳細介紹了。

對於開發者來說,rel="noreferrer"屬性是最簡單的一種方法。<a><area><form>三個標籤可以使用這個屬性,一旦使用,該元素就不會傳送Referer欄位。


<a href="..." rel="noreferrer" target="_blank">xxx</a>

上面連結點選產生的 HTTP 請求,不會帶有Referer欄位。

注意,rel="noreferrer"採用的是正確的拼寫。

五、Referrer Policy 的值

rel屬性只能定製單個元素的Referer行為,而且選擇比較少,只能傳送或不傳送。W3C 為此制定了更強大的 Referrer Policy

Referrer Policy 可以設定8個值。

(1)no-referrer

不傳送Referer欄位。

(2)no-referrer-when-downgrade

如果從 HTTPS 網址連結到 HTTP 網址,不傳送Referer欄位,其他情況傳送(包括 HTTP 網址連結到 HTTP 網址)。這是瀏覽器的預設行為。

(3)same-origin

連結到同源網址(協議+域名+埠 都相同)時傳送,否則不傳送。注意,https://foo.com連結到http://foo.com也屬於跨域。

(4)origin

Referer欄位一律只傳送源資訊(協議+域名+埠),不管是否跨域。

(5)strict-origin

如果從 HTTPS 網址連結到 HTTP 網址,不傳送Referer欄位,其他情況只傳送源資訊。

(6)origin-when-cross-origin

同源時,傳送完整的Referer欄位,跨域時傳送源資訊。

(7)strict-origin-when-cross-origin

同源時,傳送完整的Referer欄位;跨域時,如果 HTTPS 網址連結到 HTTP 網址,不傳送Referer欄位,否則傳送源資訊。

(8)unsafe-url

Referer欄位包含源資訊、路徑和查詢字串,不包含錨點、使用者名稱和密碼。

六、Referrer Policy 的用法

Referrer Policy 有多種使用方法

(1)HTTP 頭資訊

伺服器傳送網頁的時候,透過 HTTP 頭資訊的Referrer-Policy告訴瀏覽器。


Referrer-Policy: origin

(2)<meta>標籤

也可以使用<meta>標籤,在網頁頭部設定。


<meta name="referrer" content="origin">

(3)referrerpolicy屬性

<a><area><img><iframe><link>標籤,可以設定referrerpolicy 屬性。


<a href="..." referrerpolicy="origin" target="_blank">xxx</a>

七、退出頁面重定向

還有一種比較老式的技巧,但是非常有效,可以隱藏掉原始網址,谷歌和 Facebook 都在使用這種方法。

連結的時候,不要直接跳轉,而是透過一個重定向網址,就像下面這樣。


<a  href="/exit.php?url=http%3A%2F%2Fexample.com">Example.com</a>

上面網址中,先跳轉到/exit.php,然後再跳轉到目標網址。這時,Referer欄位就不會包含原始網址。

(完)

相關文章