什么是最可靠的方式来隐藏/恶搞引用JavaScript的?
通常,引用者可以通过以下方式进行追踪:
-  JavaScript的document.referrer
-  请求标头,例如PHP的$_SERVER['HTTP_REFERER']
为了testing的目的,我build立了一个显示这些属性的键盘演示程序 。
要求:
- 原始引用者应该隐藏,至less对于所有的鼠标事件。
- 跨浏览器支持(至lessChrome和Firefox)。
- 独立,没有任何外部内容(插件,库,redirect页面,…)。
- 没有副作用:链接不应该被重写,历史条目应该被保留 。
 在<a href="url">链接时,该解决scheme将用于隐藏引用链接。 
用例的精确描述
正如在这个关于Webapps的问题中所描述的那样,Googlesearch的链接在点击时被修改。 所以,
- Google能够追踪您的搜寻行为(Privacy–)
- 页面请求稍微延迟。
- 链接的页面无法跟踪您的Googlesearch查询(Privacy ++)
-  拖动/复制的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,…
-   keydown( Tab Tab Tab … Enter )。
码:
 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 Tab … Contextmenu
 在Firefox中, click事件是为每个mouseup触发的, 并在链接(或表单控件)上mouseup Enter 。  contextmenu事件是必需的,因为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,图像,脚本,其他资源…)并导航到另一个页面。
你要求的东西不能在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方法的表单。