44

通常,引荐来源网址可通过以下方式进行追踪:

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

我已经设置了一个显示这些属性的键盘演示,用于测试目的。

#要求:

  1. 至少对于所有鼠标事件,应该有效地隐藏原始引荐来源网址。
  2. 跨浏览器支持(至少 Chrome 和 Firefox)。
  3. 独立的,没有任何外部内容(插件、库、重定向页面……)。
  4. 无副作用:不应重写链接保留历史条目。

该解决方案将用于在点击链接时隐藏引荐来源网址<a href="url">


##用例的准确描述如Webapps 上的这个问题中所述,Google 搜索中的链接在点击时会被修改。最后,

  1. 谷歌能够跟踪您的搜索行为(隐私--)
  2. 页面请求略有延迟。
  3. 链接页面无法跟踪您的 Google 搜索查询(隐私++)
  4. 拖动/复制的 URL 看起来像http://google.com/lotsoftrash?url=actualurl.

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

第 3 点仍然存在。

  • 铬合金:<a rel="noreferrer">
  • 火狐:data-URIs。我已经创建了一种复杂的方法来为左键和中键实现此功能,同时仍然执行第 4 点。但是,我正在努力使用右键单击方法。
4

10 回答 10

40

我找到了适用于 Chrome 和 Firefox 的解决方案。我已经在用户脚本中实现了代码,不要跟踪我 Google

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

Webkit (Chrome, ..) 和 Firefox 37+ (33+*) 的引用隐藏

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

  • mousedown- 单击时,中键单击,右键单击上下文菜单,...
  • 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);

*rel=noreferrer从 33 开始在 Firefox 中受支持,但支持仅限于页内链接。当用户通过上下文菜单打开选项卡时,仍然会发送推荐人。此错误已在 Firefox 37 [错误 1031264 ]中修复。

隐藏旧 Firefox 版本的引荐来源网址

Firefoxrel="noreferrer"直到版本 33 ` [ bug 530396 ](或 37,如果您还希望隐藏上下文菜单的引用者)才支持。

data-URI +<meta http-equiv=refresh>可用于在 Firefox(和 IE)中隐藏引荐来源网址。实现这个特性比较复杂,但也需要两个事件:

  • click- 单击时,中键单击时,Enter
  • contextmenu- 在右键单击时,Tab Tab...Contextmenu

在 Firefox 中,click每个事件都会触发mouseup 点击Enter链接(或表单控件)。该contextmenu事件是必需的,因为click对于这种情况,事件触发得太晚了。

基于 data-URIs 和瞬间超时:
click事件被触发时,href属性会临时替换为 data-URI。事件结束,默认行为发生:打开 data-URI,取决于target属性和 SHIFT/CTRL 修饰符。
同时,href属性恢复到原来的状态。

contextmenu事件被触发时,链接也会在一瞬间发生变化。

  • 这些Open Link in ...选项将打开 data-URI。
  • Copy Link location选项指的是恢复的原始 URI。
  • ☹ 该Bookmark选项是指 data-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);

结合两种方法

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

于 2012-01-21T23:52:15.843 回答
10

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

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

于 2012-01-22T00:06:23.627 回答
6

根据要求,使用 JavaScript:

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

这会将以下元标记添加到网页的 head 部分:

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

自 2015 年起,这就是您防止发送 Referer 标头的方式。

于 2015-08-15T20:08:39.377 回答
3

Javascript 中有一个跨浏览器解决方案可以删除引用者,它使用动态创建的 iframe,您可以查看概念证明(免责声明:它使用了我编写的一个小 JS 库)。

于 2012-10-05T11:28:02.883 回答
3

您可以使用新的Referrer Policy 标准草案来防止将 referer 标头发送到请求源。例子:

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

尽管 Chrome 和 Firefox 已经实施了推荐人政策的草案版本,但您应该小心它,因为例如 Chrome 期望no-referrer而不是none(我也在never某处看到过)。如果您只添加三个单独的元标记,我不知道行为,但如果这不起作用,您仍然可以只实现一个简短的脚本,它遍历所有三个值并检查在设置属性后是否真的设置了值/元标记的属性。

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

于 2015-03-03T15:59:56.857 回答
1

可以在以下位置找到非常全面(但简短)的分析:

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

本文分析了其他答案中解释的两种方法(js 方法,iframe 重定向),最后提出了一种中介重定向器页面方法,就像在谷歌搜索链接中看到的那样。

于 2012-08-26T14:13:37.490 回答
1

您所要求的无法在 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 // <----------------
    });
}, 

显然,用户脚本不允许更改上下文菜单的实现,因此唯一的出路是浏览器扩展。

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

于 2012-01-20T13:25:14.733 回答
1

这比乍看起来要棘手。看一下这个项目的代码:

https://github.com/knu/noreferrer

他承诺了你想要的,但你必须在链接页面上做到这一点。

于 2012-01-17T11:17:43.280 回答
0

我已经使用 jquery 实现了一个简单但有效的 iframe 解决方案。

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);
于 2016-05-02T14:59:47.690 回答
-2

如果我们使用 JavaScript 提交 FORM 会怎样,这样就没有推荐人了。

document.form_name.submit()

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

于 2014-03-28T07:00:36.010 回答