什么是最可靠的方式来隐藏/恶搞引用JavaScript的?

通常,引用者可以通过以下方式进行追踪:

  • JavaScript的document.referrer
  • 请求标头,例如PHP的$_SERVER['HTTP_REFERER']

为了testing的目的,我build立了一个显示这些属性的键盘演示程序

要求:

  1. 原始引用者应该隐藏,至less对于所有的鼠标事件。
  2. 跨浏览器支持(至lessChrome和Firefox)。
  3. 独立,没有任何外部内容(插件,库,redirect页面,…)。
  4. 没有副作用:链接不应该被重写,历史条目应该被保留

<a href="url">链接时,该解决scheme将用于隐藏引用链接。


用例的精确描述

正如在这个关于Webapps的问题中所描述的那样,Googlesearch的链接在点击时被修改。 所以,

  1. Google能够追踪您的搜寻行为(Privacy–)
  2. 页面请求稍微延迟。
  3. 链接的页面无法跟踪您的Googlesearch查询(Privacy ++)
  4. 拖动/复制的url看起来像http://google.com/lotsoftrash?url=actualurl

我正在开发一个用户脚本(Firefox)/内容脚本(Chrome) ( 代码 ) ,用于删除Google的链接事件。 结果,处理了点1,2和4。

第3点仍然存在。

  • Chrome: <a rel="noreferrer">
  • Firefox: data-URIs 。 我已经创build了一个复杂的方法来实现这个function的左键和中点击,同时仍然执行第4点。 但是,我正在努力与右键单击方法。

我find了一个适用于Chrome和Firefox的解决scheme。 我已经在一个用户脚本中实现了代码, 不要跟踪我的谷歌

演示(在Firefox 9和Chrome 17中testing): http : //jsfiddle.net/RxHw5/

推荐人隐藏Webkit(Chrome,..)和Firefox 37 +(33 + *)

基于Webkit的浏览器(例如Chrome,Safari) 支持 <a rel="noreferrer"> 规范
通过将此方法与两个事件侦听器相结合,可以完全实现引荐者隐藏:

  • mousedown – 单击,中键单击,右键单击contextmenu,…
  • keydownTab Tab TabEnter )。

码:

 function hideRefer(e) { var a = e.target; // The following line is used to deal with nested elements, // such as: <a href="."> Stack <em>Overflow</em> </a>. if (a && a.tagName !== 'A') a = a.parentNode; if (a && a.tagName === 'A') { a.rel = 'noreferrer'; } } window.addEventListener('mousedown', hideRefer, true); window.addEventListener('keydown', hideRefer, true); 

Firefox自33年起支持rel=noreferrer ,但支持仅限于页内链接。 当用户通过上下文菜单打开标签时,引用者仍然被发送。 这个bug在Firefox 37 [ bug 1031264 ]中修复

推荐人隐藏旧的Firefox版本

在版本33之前,Firefox不支持rel="noreferrer" [ bug 530396 ] (或37,如果你希望隐藏引用程序的上下文菜单)。

可以使用data-URI + <meta http-equiv=refresh>来隐藏Firefox(和IE)中的引用链接。 实现这个function比较复杂,但也需要两个事件:

  • click – 点击,点击中键, 回车
  • contextmenu – 右键点击Tab TabContextmenu

在Firefox中, click事件是为每个mouseup触发的, 在链接(或表单控件)上mouseup Entercontextmenu事件是必需的,因为click事件对于这种情况来说太晚了。

基于数据URI和分秒的超时:
click事件被触发时, href属性被临时replace为data-URI。 事件结束,并发生默认行为:根据target属性和SHIFT / CTRL修饰符打开data-URI。
同时, href属性恢复到原来的状态。

contextmenu事件被触发时,链接也contextmenu改变。

  • Open Link in ...选项将打开数据URI。
  • Copy Link location选项引用已恢复的原始URI。
  • Bookmark选项是指数据URI。
  • Save Link as指向data-URI。

码:

 // Create a data-URI, redirection by <meta http-equiv=refresh content="0;url=.."> function doNotTrack(url) { // As short as possible. " can potentially break the <meta content> attribute, // # breaks the data-URI. So, escape both characters. var url = url.replace(/"/g,'%22').replace(/#/g,'%23'); // In case the server does not respond, or if one wants to bookmark the page, // also include an anchor. Strictly, only <meta ... > is needed. url = '<title>Redirect</title>' + '<a href="' +url+ '" style="color:blue">' +url+ '</a>' + '<meta http-equiv=refresh content="0;url=' +url+ '">'; return 'data:text/html,' + url; } function hideRefer(e) { var a = e.target; if (a && a.tagName !== 'A') a = a.parentNode; if (a && a.tagName === 'A') { if (e.type == 'contextmenu' || e.button < 2) { var realHref = a.href; // Remember original URI // Replaces href attribute with data-URI a.href = doNotTrack(a.href); // Restore the URI, as soon as possible setTimeout(function() {a.href = realHref;}, 4); } } } document.addEventListener('click', hideRefer, true); document.addEventListener('contextmenu', hideRefer, true); 

结合这两种方法

不幸的是,没有直接的function检测这个function的方法(更不用说考虑错误了)。 因此,您可以select基于navigator.userAgent的相关代码(即UA嗅探),也可以使用其中一种复杂的检测方法, 如何检测rel =“noreferrer”支持? 。

你不能创build一个驻留在iframe中的链接系统吗?

如果在每个链接周围包装一个iframe,iframe可以作为一个外部取消引用。 用户将点击框架内的链接,打开一个页面,其引用者被设置为iFrame的位置,而不是实际的页面。

按照要求,通过使用JavaScript:

 var meta = document.createElement('meta'); meta.name = "referrer"; meta.content = "no-referrer"; document.getElementsByTagName('head')[0].appendChild(meta); 

这将添加以下meta标签到网页的头部分:

 <meta name="referrer" content="no-referrer" /> 

截至2015年,这是你如何防止发送Referer头。

Javascript中有一个跨浏览器的解决scheme,它删除了引用,它使用dynamic创build的iframe,你可以看一看概念certificate (免责声明:它使用我写的一个小的JS库)。

您可以使用新的引用策略标准草案来防止引用标头被发送到请求源。 例:

 <meta name="referrer" content="none"> 

尽pipeChrome和Firefox已经实施了Referrer Policy的草稿版本,但您应该小心,因为例如,Chrome预计no-referrer none (而且我也never见过)。 我不知道如果你只是添加三个单独的元标记的行为,但如果不起作用,你可以仍然只是实现一个简短的脚本遍历所有三个值,并检查值是否真的设置后,属性/ meta标签的属性。

这个元标记适用于当前页面上的所有请求(ajax,图像,脚本,其他资源…)并导航到另一个页面。

这比一见钟情更棘手。 看看这个项目的代码:

https://github.com/knu/noreferrer

他承诺你想要什么,但你必须在链接页面上做。

你要求的东西不能在Firefox中完成。

当前的上下文菜单实现总是将当前文档作为引用来传递:

 // Open linked-to URL in a new window. openLink: function () { var doc = this.target.ownerDocument; urlSecurityCheck(this.linkURL, doc.nodePrincipal); openLinkIn(this.linkURL, "window", { charset: doc.characterSet, referrerURI: doc.documentURIObject // <---------------- }); }, // Open linked-to URL in a new tab. openLinkInTab: function () { var doc = this.target.ownerDocument; urlSecurityCheck(this.linkURL, doc.nodePrincipal); openLinkIn(this.linkURL, "tab", { charset: doc.characterSet, referrerURI: doc.documentURIObject // <---------------- }); }, // open URL in current tab openLinkInCurrent: function () { var doc = this.target.ownerDocument; urlSecurityCheck(this.linkURL, doc.nodePrincipal); openLinkIn(this.linkURL, "current", { charset: doc.characterSet, referrerURI: doc.documentURIObject // <---------------- }); }, 

显然,userscripts不允许改变上下文菜单的实现,所以唯一的出路是浏览器扩展。

(或者,这将是一个非常糟糕的黑客,通过调用contextmenu事件的preventDefault()禁用上下文菜单,并使用自己的自定义上下文菜单)

一个非常全面(但很短)的分析可以在以下urlfind:

http://lincolnloop.com/blog/2012/jun/27/referrer-blocking-hard/

本文分析了其他解释(js方法,iframeredirect)中解释的两种方法,并最终提出了一种中介redirect页面方法,就像在Googlesearch链接中看到的一样。

我已经实现了一个简单而有效的使用jQuery的iframe解决scheme。

https://jsfiddle.net/skibulk/0oebphet/

 (function($){ var f = $('<iframe src="about:blank" style="display: none !important;">').appendTo('body'); $('a[rel~=noreferrer]').click(function(event){ var a = $(event.target.outerHTML); a.appendTo(f.contents().find('body')); a[0].click(); return false; }); })(jQuery); 

如果我们使用JavaScript提交表单,这样就不会有引用。

 document.form_name.submit() 

基本上我们提交了一个所需的ACTION方法的表单。

Interesting Posts