在 JavaScript 中隐藏/欺骗引用者的最可靠方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8893269/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 07:57:49  来源:igfitidea点击:

What is the most reliable way to hide / spoof the referrer in JavaScript?

javascriptmouseeventtrackingreferrerspoofing

提问by Rob W

Normally, the referrer is traceable through:

通常,推荐人可以通过以下方式进行追踪:

  • JavaScript's document.referrer
  • The request headers, e.g. PHP's $_SERVER['HTTP_REFERER']
  • JavaScript的 document.referrer
  • 请求标头,例如 PHP 的 $_SERVER['HTTP_REFERER']

I have set up a Codepad demowhich shows these properties, for testing purposes.

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

Requirements:

要求:

  1. The original referrer should effectively be hidden, at least for all mouse events.
  2. Cross-browser support (at least Chrome and Firefox).
  3. Stand-alone, without any external content (plugins, libraries, redirection pages, ...).
  4. No side-effects: Links should notbe rewritten, history entries should be preserved.
  1. 应该有效地隐藏原始引用,至少对于所有鼠标事件。
  2. 跨浏览器支持(至少 Chrome 和 Firefox)。
  3. 独立的,没有任何外部内容(插件、库、重定向页面等)。
  4. 无副作用:友情链接应该没有被改写,历史条目应当保留

The solution will be used to hide the referrer when following a link of <a href="url">.

该解决方案将用于在关注<a href="url">.



Exact description of the use-case

用例的准确描述

As described in this question on Webapps, links at Google Search are modified on click. Consequently,

Webapps 上的这个问题所述,Google 搜索中的链接会在点击时进行修改。最后,

  1. Google is able to track your search behaviour (Privacy-- )
  2. The page request is slightly delayed.
  3. The linked page cannot track your Google search query (Privacy++ )
  4. Dragged/Copied URLs look like http://google.com/lotsoftrash?url=actualurl.
  1. Google 能够跟踪您的搜索行为(隐私 - )
  2. 页面请求稍有延迟。
  3. 链接页面无法跟踪您的 Google 搜索查询(隐私 ++)
  4. 拖动/复制的 URL 看起来像http://google.com/lotsoftrash?url=actualurl.

I'm developing a Userscript (Firefox) / Content script (Chrome)(code), which removes Google's link-mutilating event. As a result, points 1, 2 and 4 are dealt with.

我正在开发一个Userscript (Firefox) / Content script (Chrome) ( code),它删除了谷歌的链接破坏事件。结果,处理了第 1、2 和 4 点。

Point 3 remains.

第 3 点仍然存在。

  • Chrome: <a rel="noreferrer">
  • Firefox: data-URIs. I have created a sophisticated approach to implement this feature for left- and middle-clicks, while still enforcing point 4. However, I'm struggling with the right-click method.
  • 铬合金: <a rel="noreferrer">
  • 火狐:data-URIs。我已经创建了一种复杂的方法来为左键和中键单击实现此功能,同时仍然执行第 4 点。但是,我正在努力使用右键单击方法。

采纳答案by Rob W

I have found a solution which works in Chrome and Firefox. I've implemented the code in a Userscript, Don't track me Google.

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

Demo (tested in Firefox 9 and Chrome 17): http://jsfiddle.net/RxHw5/

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

Referrer hiding for Webkit (Chrome, ..) and Firefox 37+ (33+*)

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

Webkit-based browsers (such as Chrome, Safari) support<a rel="noreferrer">spec.
Referrer hiding can fully be implemented by combining this method with two event listeners:

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

  • mousedown- On click, middle-click, right-click contextmenu, ...
  • keydown(TabTabTab... Enter).
  • mousedown- 单击、中键、右键单击上下文菜单,...
  • keydownTabTabTab…… Enter)。

Code:

代码:

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=noreferreris supported in Firefox since 33, but support was limited to in-page links. Referrers were still sent when the user opened the tab via the context menu. This bug was fixed in Firefox 37[bug 1031264].

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

Referrer hiding for old Firefox versions

旧 Firefox 版本的引用隐藏

Firefox did not support rel="noreferrer"until version 33 `[bug 530396](or 37, if you wish to hide the referrer for context menus as well).

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

A data-URI + <meta http-equiv=refresh>can be used to hide the referrer in Firefox (and IE). Implementing this feature is more complicated, but also requires two events:

数据 URI +<meta http-equiv=refresh>可用于在 Firefox(和 IE)中隐藏引用。实现这个功能比较复杂,还需要两个事件:

  • click- On click, on middle-click, Enter
  • contextmenu- On right-click, TabTab... Contextmenu
  • click- 单击时,中键时, Enter
  • contextmenu- 右键单击​​,TabTab...Contextmenu

In Firefox, the clickevent is fired for each mouseupandhitting Enteron a link (or form control). The contextmenuevent is required, because the clickevent fires too late for this case.

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

Based on data-URIs and split-second time-outs:
When the clickevent is triggered, the hrefattribute is temporarily replaced with a data-URI. The event finished, and the default behaviour occurs: Opening the data-URI, dependent on the targetattribute and SHIFT/CTRL modifiers.
Meanwhile, the hrefattribute is restored to its original state.

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

When the contextmenuevent is triggered, the link also changes for a split second.

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

  • The Open Link in ...options will open the data-URI.
  • The Copy Link locationoption refers to the restored, original URI.
  • ? The Bookmarkoption refers to the data-URI.
  • ? Save Link aspoints to the data-URI.
  • 这些Open Link in ...选项将打开数据 URI。
  • Copy Link location选项指的是恢复的原始 URI。
  • ? 该Bookmark选项是指数据 URI。
  • ? Save Link as指向数据URI。

Code:

代码:

// 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);

Combining both methods

结合两种方法

Unfortunately, there is no straightforward way to feature-detect this feature (let alone account for bugs). So you can either select the relevant code based on navigator.userAgent(i.e. UA-sniffing), or use one of the convoluted detection methods from How can I detect rel="noreferrer" support?.

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

回答by fmsf

Can't you create a linking system that resides within iframes?

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

If you wrap an iframe around every link, the iframe can act as an external de-refer. The user would click on the link inside the frame, opening a page whose referrer is set to the iFrame's location, instead of the actual page.

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

回答by MarcG

As requested, by using JavaScript:

根据要求,通过使用 JavaScript:

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

This will add the following meta tag to head section of the web page:

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

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

As of 2015this is how you prevent sending the Referer header.

截至 2015 年,这是您阻止发送 Referer 标头的方式。

回答by jpgerek

There is a cross browser solution in Javascript that removes the referrer, it uses Iframes created dynamically, you can take a look to a proof of concept( disclaimer: it uses a little JS library I wrote ).

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

回答by Joel Richard

You could use the new Referrer Policy standard draftto prevent that the referer header is sent to the request origin. Example:

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

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

Although Chrome and Firefox have already implemented a draft version of the Referrer Policy, you should be careful with it because for example Chrome expects no-referrerinstead of none(and I have also seen neversomewhere). I don't know the behaviour if you just add three separate meta tags, but in case that does not work you could still just implement a short script which iterates over all three values and checks if the value was really set after setting the attribute/property of the meta tag.

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

This meta tag applies to all requests on the current page (ajax, images, scripts, other resources...) and navigation to another page.

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

回答by Amir Ali Akbari

A very comprehensive (but short) analysis can be found at:

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

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

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

this article analyses both methods explained in other answers (js method, iframe redirecting) and finally suggest a mediate redirector page approach, like the one seen in google search links.

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

回答by Boldewyn

This is trickier than it might seem on first sight. Look at the code of this project:

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

https://github.com/knu/noreferrer

https://github.com/knu/noreferrer

He promises quite what you want, but you have to do it on the linking page.

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

回答by user123444555621

What you're asking for cannot be done in Firefox.

您所要求的无法在 Firefox 中完成。

The current context menu implementationalways passes the current document as a referrer:

目前的上下文菜单中执行总是通过当前文档的引用:

// 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 // <----------------
    });
}, 

Obviously, userscripts are not allowed to change the context menu implementation, so the only way out is a browser extension.

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

(Or, which would be a pretty poor hack, disable the context menu by calling preventDefault()on the contextmenuevent, and use your own custom context menu)

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

回答by skibulk

I have implemented a simple but effective iframe solution using jquery.

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

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

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);

回答by highwingers

what if we submit a FORM using JavaScript, this way there will be no referrer.

如果我们使用 JavaScript 提交 FORM 怎么办,这样就没有引用者了。

document.form_name.submit()

basically we are submit a form with desired ACTIONmethod.

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