JavaScript中的document.referrer在各种浏览器测试结果
前段时间需要通过JavaScript获取页面的来源,这个操作很简单,使用document.referrer就可以获取到了。不过,实际应用中还是有很多意外情况,这儿简单整理一下。
首先遇到的问题,是从HTTPS页面转到HTTP页面后,document.referrer的值为空。出于安全性考虑,很多网站的一些重要页面(比如淘宝的登录页面)都会使用HTTPS协议。如果某个未登录用户在页面A(HTTP页面)点击了页面B(HTTP页面)的链接,但页面B需要用户登录,于是先跳到登录页面(HTTPS页面),登录完成之后再跳回B(HTTP页面),这时你会发现B页面上取不到document.referrer了。也就是说,如果想根据referrer来还原用户访问路径的话,如果路径中有HTTP页面也有HTTPS页面,那么这个路径就会在从HTTPS到HTTP的地方断掉。
这个问题的根源是浏览器的安全策略,只靠JavaScript似乎没有特别好的解决办法。一个迂回的思路是使用window.name,在HTTPS页面将当前页面的url写到window.name中,再在下一个页面(HTTP页面)读取。
除了这种情况,其它页面跳转是否都能正常取到document.referrer呢?我搜索了一番,发现这儿有人整理了一个列表,不过不是很全,例如没有包括垂而不死的IE6的情况。于是便自己动手,在虚拟机里装了N个浏览器,把各种情况都测试了一下(这真是一个体力活),结果见下表:
操作
IE6
IE7
IE8
IE9
Firefox
Chrome
Opera
Safari
直接在地址栏输入URL
“”
“”
“”
“”
“”
“”
“”
“”
从书签访问URL
“”
“”
“”
“”
“”
“”
“”
“”
从页面A点击超链接,跳转到页面B(target=”_self”)
√
√
√
√
√
√
√
√
从页面A点击超链接,跳转到页面B(target=”_blank”)
√
√
√
√
√
√
√
√
从页面A右键单击超链接,在新标签页中打开页面B
-
√
√
√
√
√
√
“”
从页面A右键单击超链接,在新窗口中打开页面B
√
√
√
√
√
√
√
“”
拖动链接到地址栏
“”
无法拖动
无法拖动
“”
“”
“”
“”
“”
拖动链接到标签栏
-
“”
“”
“”
“”
“”
“”
“”
使用浏览器的前进、后退按钮
√
√
√
√
√
√
√
√
JS修改location.href
“”
“”
“”
√
√
√
√
√
JS使用window.open
“”
“”
“”
“”
√
√
√
√
服务器重定向(302跳转)
定向之前的页面
定向之前的页面
定向之前的页面
定向之前的页面
定向之前的页面
定向之前的页面
定向之前的页面
定向之前的页面
页面MetaRefresh
“”
“”
“”
“”
“”
转向页
转向页
转向页
上表中的“√”表示能正常取到referrer,””表示referrer为空。
除了IE外,其它浏览器都是目前官网上能下载到的最新版本,其中Safari同时测试了Windows版和Mac版,结论一样。
另外还有一些情况未做测试,例如点击Flash跳转时各浏览器下能否保持referrer等。
上表中大部分情况是符合预期的,不过似乎也有几处需要注意的:
1、在Safari中,右键打开链接会丢失referrer;
2、在IE中,修改location.href或使用window.open打开页面会丢失referrer(IE9有一点例外,使用location.href跳转不会丢失referrer);
3、使用meta跳转时,IE/Firefox下会丢失referrer。
最后,一个简单的结论是:如果你需要通过document.referrer采集页面访问来源,最好不要使用JS跳转或打开新窗口,也不要使用meta跳转。