前言
在JavaScript中,document對象有很多屬性,其中有3個與對網頁的請求有關的屬性,它們分别是URL、domain和referrer。
URL屬性包含頁面完整的URL,domain屬性中隻包含頁面的域名,而referrer屬性中則儲存着連結到目前頁面的那個頁面的URL。
前面兩個很好了解,而referrer屬性簡單來說就是上一個頁面的URL。那麼這個屬性具體有什麼用處呢?
在H5頁面中,我們經常要在頭部加個傳回上一個頁面按鈕,就像下面這樣的:
image.png
點選左側的元素可以傳回到上一個頁面,我們可以簡單寫一段JS代碼:
var back = document.getElementById('back'); //假設該傳回按鈕元素id為back
back.onclick = function(){
history.back(); //傳回上一個頁面,也可以寫成history.go(-1)
};
// 或者
<a id="back" href="javascript:history.back();" rel="external nofollow" ></a>
咦?上面說了這麼多,還是沒有說到document.referrer有什麼用呀!别急,前面隻是鋪墊,接下來步入正題~~~
雖說感覺上面這樣已經基本上實作了傳回上一頁的功能,但是有一種情況沒有考慮到(我們程式員還是要嚴謹一點嘛),就是假如該頁面是别人分享過來的而不是通過其他頁面進入的呢?那麼點選該按鈕将不會有任何反應,因為此時history對象中不存在曆史記錄,也就是說這是你浏覽器視窗打開時浏覽的第一個頁面。
為了優化使用者體驗,這裡通常有兩種解決方案。一種是在打開第一個頁面時不顯示傳回上一頁按鈕,另一種是點選直接跳轉到網站首頁,這可以根據産品需求來選擇合适的方案。
這裡假設選擇第一種方案,我們可以這樣寫段JS:
if(document.referrer){
back.style.display = 'block'; //預設讓其隐藏,當referrer屬性不為空時讓其顯示
}
//分享頁 傳回上一頁
if (typeof document.referrer === '') {
// 沒有來源頁面資訊的時候,改成首頁URL位址
$('.jsBack').attr('href', '/');
}
其實判斷目前頁面是否是使用者一開始打開的頁面,方法也不止通過判斷referrer屬性這一種方法,還可以通過history.length是否為零來判斷。
浏覽器支援情況:
image.png
關于HTTPS請求
如果在一張普通的HTTP頁面上點選了HTTPS的連結,那麼在https請求頭部可以附上Referer資訊,之後在HTTPS頁面中依然可以用document.referre來獲得普通的http頁面。
同樣,如果是在一張https頁面上點選了另一個HTTPS的連結,可以在請求的頭部附上Referer資訊。
但是如果是從一張https頁面點選了http連結,那麼很不幸,發送的http請求頭裡無法包含關于https頁面的資訊,這可能是出于一種對https頁面的保護措施。
僞造Referer資訊
根據上文的描述,document.referre源自于Header中的Referer。那麼如果想修改document.referre的值,理論上講,僅需要修改請求Header。可以将Header中現有的Referer替換成自己想要的值,如果原來沒有也可以添加Referer。
在用戶端,篡改Header是一件非常容易的事情。在一個頁面的http請求發出去之前,可以利用截包工具将其攔截,然後分析出頭部資訊,并且修改Referre。
搜了一下,對于FireFox可以使用RefControl插件友善的進行修改。總之,欺騙Traffic source是輕而易舉的事情。
頁面強制Refresh
<meta http-equiv="Refresh" content="5;URL=a.html">
則過5秒後浏覽器會自動向server發起a頁面請求。
經過測試,在IE8,FF3.6-FF4.0中,均不會帶有Referer資訊,但是chrome卻能夠鬼使神差的把b.html作為Referer添加進頭部。
幾種意外丢失情況:
1,直接在浏覽器中輸入位址
2,使用location.reload()重新整理(location.href或者location.replace()重新整理有資訊)
3,在微信對話框中,點選進入微信自身浏覽器,
4,掃碼進入微信或QQ的浏覽器
5,直接新視窗打開一個頁面
6,從https的網站直接進入一個http協定的網站(Chrome下親測),
7.a标簽設定rel="noreferrer"(相容IE7+)
8,meta标簽來控制不讓浏覽器發送referer
9,點選 flash 内部連結
10,Chrome4.0以下,IE 5.5+以下傳回空的字元串,使用 修改 Location 進行頁面導航的方法,會導緻在IE下丢失 referrer,這可能是IE的一個BUG
11,跨域
12,iframe隐藏
結論:如果你需要通過 document.referrer 采集頁面通路來源,最好不要使用 JS 跳轉或打開新視窗,也不要使用 meta 跳轉。
referrer 的作用:
1,統計來源,可以統計數量,可以拒絕通路
2,傳回上一頁邏輯判斷