详谈javascript中document.referrer的兼容性

本文详细解析了referrer的概念及其在网络传输中的作用,并探讨了不同浏览器环境下referrer的获取情况,以及其对广告流量监控的影响。

遇见了,却来不及相识;相识了,却来不及熟悉;熟悉了,却还是要说再见。既然每天都见面,为何不提前熟悉一下呢?

  读书是为了明理,我们还是带着问题来了解referrer的重要性和用途吧!

一:什么是referrer?

  1. referrer中文意思是:来源,推荐人。网络意义是指网站的来路,又称“来源”,HTTPReferrer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上referrer,告诉服务器用户从哪个页面链接过来的,服务器可以获得referrer的信息用于加工处理。比如:我从我的页面连接到朋友的页面,我朋友的服务器就能够从 HTTP Referer中统计出每天有多少个用户点击我主页上的链接访问他的网站。(注意:Referer其实应该是英文单词Referrer,编写http标准的人也就将错就错了。所以嘛,要敢于向权威质疑)。
   2. 因为referrer可能是私有的信息,或者可能泄露其他私有的信息来源,所以,建议用户选择是否发送reffer域。例如:浏览器客户端可能有切换选项来公开、匿名浏览,发送refererfrom信息。如果通过安全协议传输,客户端不应该在http请求中包括referer域。
   3. referrer有时候也被用作防盗链(即下载网页资源的时候判断源地址是不是在网站域名之内,否则就不能下载或者显示),比如CSDN都是通过Referer页面来判断用户是否能够下载代码或者资源。
   4. 当然,对于某些黑客可能伪造Referer来获得某些权限,在设计网站时一定需要考虑到这个问题。但是对于浏览器来说,以下情况是不会发送Referer,因为可能有潜在的安全问题:
  * 用户手动输入网址或是从收藏夹中访问
  * 对https等加密协议是不带Referrer的。
   5. 处于以上等各种原因,有时候我们通过javascript中document.referrer获取不到来源,下面总结一下我们开发过程中碰到的丢失Referrer的情况。

二: 模拟丢失Referrer的现象?

首先我们写个公用的test代码,test.html页面的代码是:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title> 
    </head>
    <body>
        欢迎来到test页面
    </body>
    <script>
        alert('来源是:'+ document.referrer);
    </script>
</html>

  1. window.open方式打开新窗口

//方法一:直接用window.open()跳转在ie6,7,8 11丢失Referrer ,在edge,opera、chrome、Firefox都能拿到Referrer,看来用window.open()直接,去来源对于新一代浏览器都不适用。
    window.open('test.html');//

下面是用windows.open()里面的内容进行间接跳转,都是精心测试的结果:

        var url = 'http://localhost/04interesting/11js/05js-Internet/01referer/all/test.html';

        //方法二:window.location.href在每个浏览器都可以获取referrer
       window.location.href = 'test.html';

        //方法三:opera,chrome,edge,ie11,qq,uc,丢失referrer,但是Firefox不丢失,ie6无法跳转
        window.open('javascript:window.name;','<script>location.replace("'+url+'")<\/script>');

        // 方法四:opera,chrome,qq,uc丢失referrer,但是Firefox不丢失,  ie6,ie11,edge无法跳转
        window.open('data:text/html,<html><body><script>location.replace("'+url+'")<\/script></body></html>');

        // 方法五:opera,chrome,ie6,ie11,edge,qq,uc丢失referrer ,但是Firefox不丢失,
        window.open('javascript:location.replace("' + url + '")');

        //方法六:opera,chrome Firefox,uc,qq丢失来源 ,      ie6,ie11,ie9,edge不跳转
        window.open('data:text/html,<html><head><meta http-equiv="Refresh" content="0;' + url + '"/></head><body></body></html>');

  2. 用refresh方法刷新跳转到新窗口

<!--<!DOCTYPE html>-->
<html>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="Refresh" content="0;URL=test.html">
        <title></title>
    </head>  
    <body>                             
        <a href="test.html">点我到test.html</a>    
    </body>                    
</html>

<meta http-equiv="Refresh" content="0;URL=test.html">:总结ie6,ie11,edge,火狐不能 ,google,opera上可以获取到Referrer,另外在qq,360和uc浏览器上都可以获取来源
  3. 创建iframe的方法

        var ifm = document.createElement('iframe');
        ifm.src ='test.html'; 'javascript:"<script>top.location.replace(\'./test.html\')<\/script>"';
        document.body.appendChild(ifm);

用iframe在opera,chrome,uc,360,上获取不到Referrer, 在ie6,ie11,edge,firefox上能获取到。
  4.location.search.replace(‘?url=’,”),即:跳转代理页面的方法
我们先创建一个代理页面 middle.html

        var url = location.search.replace('?url=','');
        // location.replace(decodeURL(url));
        alert(location);
        location.replace(decodeURI(url));

然后我们通过另一个页面来跳转到middle.html页面上:

    //此方法在ie6中不能跳转
        var url = 'test.html';
        window.open('bridge.html?url='+ encodeURI(url));

  *5.用封装好的跳转js代码,通过a标签直接跳转

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <script src="../../../../../lib/jq1.8.3.jquery.mini.js" charset="utf-8"></script>
        <script src="./noreferrer.js"></script>
    </head>
    <body>
        <a href="./test.html" rel="noreferrer">点击我到test.html,而且不带来源</a>
    </body>
</html>

  6,用h5的方法大部分浏览器都获取不到来源,代码如下:
  方法一:<meta name="referrer" content="never"> 和widnow.open();

<!--<!DOCTYPE html>-->
<html>
<head>
    <meta charset="UTF-8">
    <meta name="referrer" content="never">
    <title></title>
</head>
<body>
    <a href="test.html">点我到test.html</a>
</body>
<script>
    //在ie6,ie11,360,uc,chrome,opera都不能拿到Referrer
        window.open('test.html');
</script>
</html>

  方法二:a标签中的rel=”noreferrer”

<a href="test.html" target="_blank" rel="noreferrer">点我到test.html</a>

5.鼠标拖拽文档打开窗口
  全部都丢失referrer;
6.从https地网站跳转到http的网站
  浏览器是不会发送referrer地.这个各大浏览器地行为是一样地.
例如,我们在https下使用google reader或是gmail地时候,点击某个链接去到另外一个网站,那么从技术上来说,这样地访问和用户直接键入网址访问是没有什么分别地.

三:referrer对于广告流量监控地影响?
  对于广告监控流量来说,referrer非常重要,目前国内好多用了google adsense广告的网站,都使用了window.open的方式来打开广告链接,因此,ie下会丢失referrer,由于ie在市场占得比重很大,很多流量统计工具会因此把这一部分流浪归入“直接流量”,和用户直接键入网址等价了。因此我们必须深入了解referrer在每个浏览器的落脚点。
以上均为原创,当然也有参考部分,以下是参考汇总的网址,我希望把东西分享开,如有错误请大家及时反馈,愿意分享才能让世界更美好!
http://www.cnblogs.com/zhangzt/archive/2009/12/24/1631253.html
http://www.tuicool.com/articles/YJjeq2U
http://jishu.admin5.com/biancheng/140311/840.html
http://www.gbtags.com/gb/share/4907.htm

<think> 我们被要求解释JavaScript中`location.href = document.referrer`的含义和使用。 根据提供的引用,我们可以总结如下: 1. `document.referrer`:获取当前页面的来源页面的URL(即用户是从哪个页面跳转过来的)。它相当于PHP中的`$_SERVER['HTTP_REFERER']`,但需要注意拼写是`referrer`(两个r)[^2]。 2. `location.href`:获取或设置当前页面的完整URL。当给`location.href`赋值时,浏览器会导航到该URL。 3. `location.href = document.referrer`:这行代码的作用是让浏览器跳转到来源页面(即上一页)。它实际上是执行了一次“返回”操作,但注意,这并不等同于浏览器的后退按钮(因为后退按钮是浏览历史的上一条记录,而这里直接指定了目标URL)。 使用场景: - 常见的场景是“返回”按钮的功能。当用户点击一个返回按钮时,我们可以用这行代码将用户带回到上一页面。 - 但是,需要注意`document.referrer`存在一些兼容性和使用限制: - 在Safari中,如果用户是通过右键菜单打开链接,则`document.referrer`可能为空[^4]。 - 在IE中,通过`window.open`或修改`location.href`跳转可能会丢失referrer(但IE9使用`location.href`跳转不会丢失)[^4]。 - 使用meta跳转时,IE和Firefox下会丢失referrer[^4]。 - 另外,如果用户直接在地址栏输入地址或通过书签访问,则`document.referrer`为空字符串。 因此,在实际使用中,我们需要考虑这些情况,并做好兼容性处理。例如,如果`document.referrer`为空,可能要跳转到默认页面或使用`history.back()`。 另外,引用[1]和[3]中提到了一些技巧: - 引用[1]:在跳转时拼接参数(避免缓存)时,需要判断来源URL是否已有参数,从而决定使用`?`还是`&`。 - 引用[3]:在IE中,为了保留referrer,使用了一个技巧:创建一个`<a>`标签并模拟点击,这样在跳转后,目标页面依然可以获取到referrer。 因此,我们可以这样总结: ### 含义 `location.href = document.referrer` 表示将当前页面的地址设置为来源页面的地址,从而让浏览器跳转回来源页面。 ### 使用场景 1. 实现返回上一页的功能。 2. 在需要返回到来源页面的场景,如表单提交后返回等。 ### 注意事项 1. `document.referrer`可能为空(如直接访问、书签、某些浏览器的特殊情况等),因此在使用前应检查: ```javascript if (document.referrer) { location.href = document.referrer; } else { // 没有来源页面,可以跳转到默认页面或使用history.back() history.back(); } ``` 2. 为了确保跳转后的页面不被缓存(例如,在返回时希望看到更新),可以在URL后添加随机参数(引用[1]): ```javascript if (document.referrer) { var connector = document.referrer.indexOf('?') > -1 ? '&' : '?'; location.href = document.referrer + connector + 'r=' + Math.random(); } ``` 3. 对于IE的兼容性问题,特别是需要保留referrer的情况,可以使用引用[3]中的方法(通过创建a标签并模拟点击)来跳转。 ### 示例代码 下面是一个实现返回上一页并避免缓存的函数(考虑了来源为空的情况): ```javascript function goBackWithCacheBuster() { if (document.referrer) { var connector = document.referrer.indexOf('?') > -1 ? '&' : '?'; // 添加随机参数防止缓存 location.href = document.referrer + connector + 'nocache=' + Math.random(); } else { // 如果没有来源,则使用history.back()返回,如果历史记录为空,则跳转到首页 if (history.length > 1) { history.back(); } else { location.href = '/'; // 跳转到首页或其他默认页面 } } } ``` ### 总结 `location.href = document.referrer`是一种常用的返回上一页的方法,但由于浏览器兼容性和`document.referrer`的局限性,实际使用中需要谨慎处理。建议在跳转前检查`document.referrer`是否存在,并考虑添加缓存破坏参数。在需要保留referrer的场景(如目标页面需要知道来源),可以采用创建a标签模拟点击的方法来跳转(特别是在IE中)[^3]。 §§相关问题§§ 1. 如何解决`document.referrer`在Safari或IE中为空的问题? 2. 除了`document.referrer`,还有哪些方法可以实现返回上一页的功能? 3. 如何防止浏览器缓存页面,导致返回时看不到更新? 4. 在哪些场景下使用`location.href = document.referrer`可能不安全? </think> ### `location.href = document.referrer` 的含义与作用 #### 1. **核心含义** 该代码表示 **将浏览器重定向到当前页面的来源页面(即上一页)**。 - `document.referrer`:获取当前页的来源 URL(即用户是从哪个页面跳转过来的)[^2][^4]。 - `location.href`:设置或获取当前页面的完整 URL,赋值时会触发页面跳转[^2][^5]。 组合后的效果是 **强制返回上一页**。 #### 2. **典型使用场景** - **“返回”按钮功能**: 用户点击后退按钮时,直接跳转至来源页面。 ```javascript document.getElementById("backBtn").onclick = function() { location.href = document.referrer; }; ``` - **表单提交后的跳转**: 提交表单后自动返回来源页(如商品详情页提交后返回列表页)。 - **防盗链处理**: 验证图片来源是否合法,非法则用 `location.href` 重定向至来源站[^2]。 --- ### 关键注意事项与兼容性问题 #### 1. **`document.referrer` 的可靠性** - **可能为空的情况**: - 用户直接输入地址访问(无来源页)。 - 浏览器隐私模式。 - 使用 `meta` 标签跳转(IE/Firefox 会丢失 referrer)[^4]。 - Safari 中右键打开链接[^4]。 **安全代码示例**: ```javascript if (document.referrer) { location.href = document.referrer; // 有来源页时跳转 } else { history.back(); // 无来源页时用历史记录后退 } ``` #### 2. **参数拼接问题** 向来源页添加参数时需检查 URL 是否已包含 `?`: ```javascript if (document.referrer.includes('?')) { location.href = document.referrer + "&nocache=" + Math.random(); } else { location.href = document.referrer + "?nocache=" + Math.random(); } // 添加随机参数防止缓存 [^1] ``` #### 3. **浏览器兼容性** - **IE 特殊处理**: IE 下直接修改 `location.href` 可能丢失 referrer。需用 `<a>` 标签模拟点击[^3]: ```javascript if (isIE) { const link = document.createElement('a'); link.href = document.referrer; document.body.appendChild(link); link.click(); // IE 保留 referrer 的写法 } ``` - **拼写错误**: `referrer` 易错写成 `referer`(正确拼写带两个 `r`)[^2]。 --- ### 与类似技术的对比 | **方法** | **特点** | |------------------------|--------------------------------------------------------------------------| | `history.back()` | 基于浏览器历史栈后退,不依赖 referrer,但无法跨域。 | | `location.replace()` | 替换当前页(不产生历史记录),但需手动指定 URL。 | | `location.href = ...` | 依赖 `document.referrer` 实现动态跳转,可跨域但存在兼容性问题[^4][^5]。 | --- ### 总结 - **核心作用**:模拟浏览器“返回”行为,跳转至来源页。 - **适用场景**:返回按钮、表单提交后跳转、防盗链。 - **必做检查**: 1. 验证 `document.referrer` 非空。 2. 处理参数拼接(`?` 与 `&`)。 3. 针对 IE 使用 `<a>` 标签兼容方案[^3][^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值