Document.Referrer丢失的几个原因

本文探讨了HTTP请求中referrer头的重要性,特别是在Web分析中。文章详细列举了几种referrer可能丢失的情况,包括通过修改Location对象导航、使用window.open打开新窗口、鼠标拖拽打开新窗口等,并提出了解决方案。

Referrer的重要性

HTTP请求中有一个referer的报文头,用来指明当前流量的来源参考页。例如在www.sina.com.cn/sports/上点击一个链接到达cctv.com首页,那么就referrer就是www.sina.com.cn/sports/了。在Javascript中,我们可以通过document.referrer来获取同样的信息。通过这个信息,我们就可以知道访客是从什么渠道来到当前页面的。这对于WebAnalytics来说,是非常重要的,这可以告诉我们不同渠道带来的流量的分布情况,还有用户搜索的关键词等,都是通过分析这个referrer信息来获取的。

但是,出于各种各样的原因,有时候Javascript中读到的referrer却是空字符串。下面总结一下哪些情况下会丢失referrer。

Referrer丢失的几个场景

修改Location对象进行页面导航

Location对象是一个用于页面导航的非常实用的对象。因为他允许你只变更Url的其中一部分。例如从cn域名切换到com域名,其他部分不变:

window.location.hostname = "example.com";

但 是,通过修改Location进行页面导航的方法,会导致在IE下丢失Referrer。

IE5.5+ 下返回空字符串

Chrome3.0+,Firefox3.5,Opera9.6,Safari3.2.2均正常返回来源网页

window.open 方式打开新窗口

示例:

<a href="#" onclick="window.open('http://www.google.com')">访问Google</a>

点 击此链接会在新窗口打开Google网站,我们在地址栏中输入以下js代码就可以看到发送的referrer了。

javascript:alert(document.referrer)

测 试结果:

IE5.5+ 下返回空字符串

Chrome3.0+,Firefox3.5,Opera9.6,Safari3.2.2 均正常返回来源网页

如果是同个域名下通过此方式跳转的,那么我们可以通过访问windoww.opener对象去获取丢失的referrer信息。代码如下:

<script type="text/javascript">
    var referrer = document.referrer;
    if (!referrer) {
        try {
            if (window.opener) {
                // IE下如果跨域则抛出权限异常
                // Safari和Chrome下window.opener.location没有任何属性
                referrer = window.opener.location.href;
            }
        }
        catch (e) {}
    }
</script>

跨 域的话则没辙了~

鼠标拖拽打开新窗口

鼠标拖拽是现在非常流行的用户习惯,很多浏览器都内置或者可以通过插件的方式来支持鼠标拖拽式浏览。但是通过这种方式打开的页面,基本全都丢失referrer。并且,这种情况下,也无法使用window.opener的方式去获取丢失的referrer了。

已测试:

Maxthon2.5.2,Firefox的FireGesture插件,Chrome3.0+,Opera9.6,Safari3.2。

点击Flash内部链接

点击Flash上到达另外一 个网站的时候,Referrer的情况就比较杂乱了。

IE下,通过客户端Javascript的document.referrer读取到的值是空的,但是如果你使用流量监控软件看一下的话,你会发现,实际上HTTP请求中的Referer报文头却是有值的,这可能是IE实现的Bug。同时,这个值指向的是Flash文件的地址,而不是来源网页的地址。

Chrome4.0下点击Flash到达新窗口之后,Referrer也 是指向的Flash文件的地址,而不是源网页的地址。

Chrome3.0和Safari3.2是一样的,都是会丢失Referrer信息。

Opera 则和Firefox一样,Referrer的值都是来源网页的地址。

HTTPS跳转到HTTP

从HTTPS的网站跳转到 HTTP的网站时,浏览器是不会发送referrer的。这个各大浏览器的行为是一样的。

例如,我们在HTTPS下使用GoogleReader或是Gmail的时候,点击某个链接去到另外一个网站,那么从技术上来说,这样的访问和用户直接键入网址访问是没有什么分别的。

Referrer 丢失对于广告流量监控的影响

Referrer如果丢失,WebAnalytics就会丢掉很重要的一部分信息了,特别对于广告流量来说,就无法知道实际来源了。目前国内好多用了GoogleAdsense广告的网站,都使用了window.open的方式来打开广告链接,因此IE下会丢失Referrer,而我们知道,IE是目前市场份额最大的浏览器,因此其影响是很大的。很多流量统计工具会因此将这部分流量归入“直接流量”,和用户直接键入网址等价了。

对于这样的情况,需要 让广告投放者在投放广告的时候,给着陆页面的Url加上特定的跟踪参数。

例如,某个Flash广告,点击之后到达的网址是http://www.example.com/,为了监控此流量是从哪个渠道过来的,我们可以修改此投放的着陆Url,改成http://www.example.com/?src=sina,类似这种方式,然后在着陆页面中使用Javascript代码提取此src参数,这样就可以得到广告来源信息。

在投放GoogleAdwords的时候,后台系统有一个“自动标记”的选项,当启用此选项的时候,Google在生成所有广告的着陆页面Url的时候,就会自动加上一个gclid的参数,这个参数能够将GoogleAnalytics后台和Adwords广告后台的数据进行整合。这样就可以知道广告流量对应于哪个广告系列,哪个广告来源和广告关键词等信息了。和上面提到的思路其实是类似的。只不过Google自动帮你做了Url的修改了而已。


<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]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值