javascript的document.referrer浏览器支持、失效情况总结


Posted in Javascript onJuly 18, 2014

在流量统计服务中都有Traffic source这个功能。Traffic source是针对访次级别的概念,换句话说,当访次建立的时候,landing page的流量来源即是该访次的Traffic source。虽然Traffic source有很多种,不过不幸的是依据现在JS,获得Traffic source的途径只有两种——document.referrer、window.opener.更不幸的是,window.opener适用的场景不多,而document.referrer非常的弱,以至于很多场景下无法准确判断出流量来源。

document.referrer的覆盖

从使用意义上来说document.referrer希望能够追踪到的是浏览器端行为。如果一张页面A被打开,那么浏览器端可能会发生的动作有用户操作、JS代码两种。

先来看看用户打开页面A可能会进行的操作:

1 直接在地址栏中输入A的地址
2 从B页面左击link A,跳转至A页面
3 从B页面右击link A,在新窗口中打开
4 从B页面右击link A,在新标签页中打开
5 拖动link A至地址栏
6 拖动link A至标签栏
7 使用浏览器的前进、后退按钮

注意这里的link即指<A>标签,但是如果有事件或者target还要另当别论。

JS打开页面可能的方式:

1 修改window.location
2 使用window.open
3 点击flash

上面列出了客户端打开页面的一些方法,此外,如果通过服务端的重定向技术,也能够使得页面A呈现给访客。

下面来针对具体的浏览器测试,如果是上述的这些情况,document.referrer表现如何:

序号 场景 IE8.0 FF3.6 FF4.0 chrome
1 直接在地址栏中输入A的地址 " " " " " " " "
2 从B页面左击link A,A页面替换B页面(target='_self')
3 从B页面左击link A,A在新窗口中打开(target='_blank')
3 从B页面右击link A,在新窗口中打开 " "
4 从B页面右击link A,在新标签页中打开 " "
5 鼠标拖动link A至地址栏 " " " " " "
6 鼠标拖动link A至标签栏 " " " " " " " "
7 使用浏览器的前进、后退按钮 保持 保持 保持 保持
8 修改window.location打开A页面(同域) " "
9 使用window.open打开A页面 " "
10 点击flash打开A页面
11 服务器重定向至A页面 " " " " " " " "

其中," "表示一个空的字符串,√表示能够正确判断来源页,保持则意味使用前进后退不会改变页面的referrer。从这张表里可以看出document.referrer能覆盖大约一半的case。但是对于一些比较常用的操作,例如利用鼠标拖动link至标签栏、前进后退等情况还不能做出正确的处理。

document.referrer的来源

浏览器在向server请求页面A的时候,会发送HTTP请求。这个请求的Header里会带上Referer属性,server接收到该请求后,可以提取出Header里的Referer,用于判断访客是从哪个页面发起的请求。

javascript的document.referrer浏览器支持、失效情况总结

一般情况下浏览器请求A时发送的Header中Referer是什么,那么拿到A页面后document.referre的值就是什么。上图是一个请求A页面的Header,A的document.referre为http://localhost/Test/b.html。
 
如果在Header中不包含Referre,那么用document.referre去取的时候,就会被赋值为空字符串。

关于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

写完不久就发现遗漏了一种页面跳转的方式,即在html中的meta标签里强制指定页面进行refresh。例如在b.html中写入

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

则过5秒后浏览器会自动向server发起a页面请求。
 
经过测试,在IE8,FF3.6-FF4.0中,均不会带有Referer信息,但是chrome却能够鬼使神差的把b.html作为Referer添加进头部。
Javascript 相关文章推荐
Ajax一统天下之Dojo整合篇
Mar 24 Javascript
JQuery模板插件 jquery.tmpl 动态ajax扩展
Nov 10 Javascript
js实现倒计时(距离结束还有)示例代码
Jul 24 Javascript
jQuery实现级联菜单效果(仿淘宝首页菜单动画)
Apr 10 Javascript
jquery 动态增加,减少input表单的简单方法(必看)
Oct 12 Javascript
vue轮播图插件vue-awesome-swiper的使用代码实例
Jul 10 Javascript
javascript+css3开发打气球小游戏完整代码
Nov 28 Javascript
详解VueJS应用中管理用户权限
Feb 02 Javascript
详解vue项目接入微信JSSDK的坑
Dec 14 Javascript
Next.js实现react服务器端渲染的方法示例
Jan 06 Javascript
详解JQuery基础动画操作
Apr 12 jQuery
vue项目打包后请求地址错误/打包后跨域操作
Nov 04 Javascript
jQuery控制的不同方向的滑动(向左、向右滑动等)
Jul 18 #Javascript
JQuery对表单元素的基本操作使用总结
Jul 18 #Javascript
jQuery新的事件绑定机制on()示例应用
Jul 18 #Javascript
jQuery中attr()和prop()在修改checked属性时的区别
Jul 18 #Javascript
$.each遍历对象、数组的属性值并进行处理
Jul 18 #Javascript
js 模式窗口(模式对话框和非模式对话框)的使用介绍
Jul 17 #Javascript
一个小例子解释如何来阻止Jquery事件冒泡
Jul 17 #Javascript
You might like
php获取json数据所有的节点路径
2015/05/17 PHP
详解WordPress开发中wp_title()函数的用法
2016/01/07 PHP
visual studio code 调试php方法(图文详解)
2017/09/15 PHP
jQuery 滑动方法slideDown向下滑动元素
2014/01/16 Javascript
javascript 获取iframe里页面中元素值的方法
2014/02/17 Javascript
Nodejs实现的一个简单udp广播服务器、客户端
2014/09/25 NodeJs
javascript实现类似超链接的效果
2014/12/26 Javascript
Vue.js第一天学习笔记(数据的双向绑定、常用指令)
2016/12/01 Javascript
bootstrap 设置checkbox部分选中效果
2017/04/20 Javascript
修改npm全局安装模式的路径方法
2018/05/15 Javascript
JavaScript查看代码运行效率console.time()与console.timeEnd()用法
2019/01/18 Javascript
微信小程序新手教程之页面打开数量限制
2019/03/03 Javascript
微信小程序使用echarts获取数据并生成折线图
2019/10/16 Javascript
如何使用JavaScript实现无缝滚动自动播放轮播图效果
2020/08/20 Javascript
[00:42]《辉夜杯》—职业组预选赛12月3日15点 正式打响
2015/12/03 DOTA
python单链表实现代码实例
2013/11/21 Python
python实现登陆知乎获得个人收藏并保存为word文件
2015/03/16 Python
python微信跳一跳游戏辅助代码解析
2018/01/29 Python
Python打印“菱形”星号代码方法
2018/02/05 Python
Python读取txt文件数据的方法(用于接口自动化参数化数据)
2018/06/27 Python
python_opencv用线段画封闭矩形的实例
2018/12/05 Python
Python基本数据结构之字典类型dict用法分析
2019/06/08 Python
tensorflow使用freeze_graph.py将ckpt转为pb文件的方法
2020/04/22 Python
彻底解决pip下载pytorch慢的问题方法
2021/03/01 Python
社团活动策划书范文
2014/01/09 职场文书
设计师个人求职信范文
2014/02/02 职场文书
蟋蟀的住宅教学反思
2014/04/26 职场文书
普通话演讲稿
2014/09/03 职场文书
乡镇机关党员民主评议表自我评价
2014/09/21 职场文书
领导班子专题民主生活会情况想汇报
2014/09/30 职场文书
临时工聘用合同协议书
2014/10/29 职场文书
班级元旦晚会开幕词
2015/01/29 职场文书
大学生逃课检讨书
2015/05/04 职场文书
基于Python的EasyGUI学习实践
2021/05/07 Python
Python之Matplotlib绘制热力图和面积图
2022/04/13 Python
Mysql InnoDB 的内存逻辑架构
2022/05/06 MySQL