janlay’s blog

悠悠人生路,翩翩少年情

从获取 Referrer 的方法说起

要使页面在当前页跳转到下一页,有几种实现方式:

  • HTML: 点击标准的链接
    <a href="new/path">goto</a>
  • HTTP header: 服务端跳转(301或302重定向)
    Location: http://host/new/path
  • HTML: 使用 meta 配置
    <meta http-equiv="refresh" content="1; url=new/path />"
  • JavaScript: 改变 location.href 属性
    location.href = 'new/path';
  • JavaScript: 使用 location.replace() 方法
    location.replace('new/path');

以上方法实现方式不同,可以灵活运用于不同场景。悲剧的是,虽然可以达成跳转需求,但通过一些方式跳转到新页面时不会带上引用页地址 (referrer, HTTP header 错误地把它拼写成 “referer”). 为什么需要引用页?因为:

  • 站长和产品经理们要了解用户使用自己网站的习惯,从而发现使用流程中的问题
  • 有时候服务端需要验证来源,确保点击来自指定的地址

上面说“一些方式”而没有具体指明到底是哪些,是因为实践发现,不同的浏览器甚至不同版本,在处理这些方式时,采取不同的引用页发送策略。这里有人做了很好的总结:


(image via)

表格中的浏览器比较老,不过你可以通过它提供的测试页面 验证各种方式在新浏览器中是否会发送引用。

那么有没有靠谱的方法,确保各种浏览器必然会发送引用页呢?答案是肯定的,相对繁琐一点而已。大概实现方式是这样的:

  1. 手动创建一个 <a> 标签,设置其地址为要跳转的目标地址
  2. 隐藏这个链接标签
  3. 手动调用其 click() 方法,模拟用户点击

stackoverflow 上面有人贴了代码

似乎到这里就可以结束了。不过我想探讨的是,为什么会有这些差异?

在我看来,发送引用页是浏览器负责的事情,每个浏览器及其不同版本,对是否要发送引用可能持有不同的看法,无所谓规范或标准。比如,多 tab 浏览器大多支持滚轮点击链接开新 tab, 你说这种情况下要不要发送引用呢?你可能会说:“要发送”,事实上大多数国产浏览器都不会发,而 IE 会。

另一方面,因为引用页数据是直接跟隐私相关的,所以会导致有不同的理解。比如那个 location.replace() 如果我是浏览器的 PD, 会要求不发。因为按照我的理解,这个方法的功能是,抹掉历史记录中的当前页;本地都抹掉了,从隐私保护上来说,我不希望下一个页面知道来源。

最后推荐一下我几年写的一篇相关的 blog(可能要翻墙)很青涩,勿笑~

那么,你的看法呢?

Comments