深入理解document.referrer的用法

前言
在JavaScript中,document對(duì)象有很多屬性,其中有3個(gè)與對(duì)網(wǎng)頁的請(qǐng)求有關(guān)的屬性,它們分別是URL、domain和referrer。
URL屬性包含頁面完整的URL,domain屬性中只包含頁面的域名,而referrer屬性中則保存著鏈接到當(dāng)前頁面的那個(gè)頁面的URL。
前面兩個(gè)很好理解,而referrer屬性簡單來說就是上一個(gè)頁面的URL。那么這個(gè)屬性具體有什么用處呢?
在H5頁面中,我們經(jīng)常要在頭部加個(gè)返回上一個(gè)頁面按鈕,就像下面這樣的:

image.png

點(diǎn)擊左側(cè)的元素可以返回到上一個(gè)頁面,我們可以簡單寫一段JS代碼:

var back = document.getElementById('back'); //假設(shè)該返回按鈕元素id為back
back.onclick = function(){
 history.back(); //返回上一個(gè)頁面,也可以寫成history.go(-1)
};
// 或者
<a id="back" href="javascript:history.back();" rel="external nofollow" ></a>

咦?上面說了這么多,還是沒有說到document.referrer有什么用呀!別急,前面只是鋪墊,接下來步入正題~~~
雖說感覺上面這樣已經(jīng)基本上實(shí)現(xiàn)了返回上一頁的功能,但是有一種情況沒有考慮到(我們程序員還是要嚴(yán)謹(jǐn)一點(diǎn)嘛),就是假如該頁面是別人分享過來的而不是通過其他頁面進(jìn)入的呢?那么點(diǎn)擊該按鈕將不會(huì)有任何反應(yīng),因?yàn)榇藭r(shí)history對(duì)象中不存在歷史記錄,也就是說這是你瀏覽器窗口打開時(shí)瀏覽的第一個(gè)頁面。
為了優(yōu)化用戶體驗(yàn),這里通常有兩種解決方案。一種是在打開第一個(gè)頁面時(shí)不顯示返回上一頁按鈕,另一種是點(diǎn)擊直接跳轉(zhuǎn)到網(wǎng)站首頁,這可以根據(jù)產(chǎn)品需求來選擇合適的方案。
這里假設(shè)選擇第一種方案,我們可以這樣寫段JS:

if(document.referrer){
 back.style.display = 'block'; //默認(rèn)讓其隱藏,當(dāng)referrer屬性不為空時(shí)讓其顯示
}
//分享頁 返回上一頁
if (typeof document.referrer === '') {
 // 沒有來源頁面信息的時(shí)候,改成首頁URL地址
 $('.jsBack').attr('href', '/');
}

其實(shí)判斷當(dāng)前頁面是否是用戶一開始打開的頁面,方法也不止通過判斷referrer屬性這一種方法,還可以通過history.length是否為零來判斷。
瀏覽器支持情況:

image.png

關(guān)于HTTPS請(qǐng)求
如果在一張普通的HTTP頁面上點(diǎn)擊了HTTPS的鏈接,那么在https請(qǐng)求頭部可以附上Referer信息,之后在HTTPS頁面中依然可以用document.referre來獲得普通的http頁面。

同樣,如果是在一張https頁面上點(diǎn)擊了另一個(gè)HTTPS的鏈接,可以在請(qǐng)求的頭部附上Referer信息。

但是如果是從一張https頁面點(diǎn)擊了http鏈接,那么很不幸,發(fā)送的http請(qǐng)求頭里無法包含關(guān)于https頁面的信息,這可能是出于一種對(duì)https頁面的保護(hù)措施。
偽造Referer信息
根據(jù)上文的描述,document.referre源自于Header中的Referer。那么如果想修改document.referre的值,理論上講,僅需要修改請(qǐng)求Header??梢詫eader中現(xiàn)有的Referer替換成自己想要的值,如果原來沒有也可以添加Referer。

在客戶端,篡改Header是一件非常容易的事情。在一個(gè)頁面的http請(qǐng)求發(fā)出去之前,可以利用截包工具將其攔截,然后分析出頭部信息,并且修改Referre。

搜了一下,對(duì)于FireFox可以使用RefControl插件方便的進(jìn)行修改??傊垓_Traffic source是輕而易舉的事情。

頁面強(qiáng)制Refresh

<meta http-equiv="Refresh" content="5;URL=a.html">

則過5秒后瀏覽器會(huì)自動(dòng)向server發(fā)起a頁面請(qǐng)求。

經(jīng)過測試,在IE8,F(xiàn)F3.6-FF4.0中,均不會(huì)帶有Referer信息,但是chrome卻能夠鬼使神差的把b.html作為Referer添加進(jìn)頭部。
幾種意外丟失情況:
1,直接在瀏覽器中輸入地址
2,使用location.reload()刷新(location.href或者location.replace()刷新有信息)
3,在微信對(duì)話框中,點(diǎn)擊進(jìn)入微信自身瀏覽器,
4,掃碼進(jìn)入微信或QQ的瀏覽器
5,直接新窗口打開一個(gè)頁面
6,從https的網(wǎng)站直接進(jìn)入一個(gè)http協(xié)議的網(wǎng)站(Chrome下親測),
7.a標(biāo)簽設(shè)置rel="noreferrer"(兼容IE7+)
8,meta標(biāo)簽來控制不讓瀏覽器發(fā)送referer
9,點(diǎn)擊 flash 內(nèi)部鏈接
10,Chrome4.0以下,IE 5.5+以下返回空的字符串,使用 修改 Location 進(jìn)行頁面導(dǎo)航的方法,會(huì)導(dǎo)致在IE下丟失 referrer,這可能是IE的一個(gè)BUG
11,跨域
12,iframe隱藏

結(jié)論:如果你需要通過 document.referrer 采集頁面訪問來源,最好不要使用 JS 跳轉(zhuǎn)或打開新窗口,也不要使用 meta 跳轉(zhuǎn)。
referrer 的作用:
1,統(tǒng)計(jì)來源,可以統(tǒng)計(jì)數(shù)量,可以拒絕訪問
2,返回上一頁邏輯判斷

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容