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
欄位就不會包含原始網址。
(完)