在 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
What is the most reliable way to hide / spoof the referrer in JavaScript?
提问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:
要求:
- The original referrer should effectively be hidden, at least for all mouse events.
- Cross-browser support (at least Chrome and Firefox).
- Stand-alone, without any external content (plugins, libraries, redirection pages, ...).
- No side-effects: Links should notbe rewritten, history entries should be preserved.
- 应该有效地隐藏原始引用,至少对于所有鼠标事件。
- 跨浏览器支持(至少 Chrome 和 Firefox)。
- 独立的,没有任何外部内容(插件、库、重定向页面等)。
- 无副作用:友情链接应该没有被改写,历史条目应当保留。
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 搜索中的链接会在点击时进行修改。最后,
- Google is able to track your search behaviour (Privacy-- )
- The page request is slightly delayed.
- The linked page cannot track your Google search query (Privacy++ )
- Dragged/Copied URLs look like
http://google.com/lotsoftrash?url=actualurl
.
- Google 能够跟踪您的搜索行为(隐私 - )
- 页面请求稍有延迟。
- 链接页面无法跟踪您的 Google 搜索查询(隐私 ++)
- 拖动/复制的 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
- 单击、中键、右键单击上下文菜单,...keydown
(TabTabTab…… 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=noreferrer
is 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, Entercontextmenu
- On right-click, TabTab... Contextmenu
click
- 单击时,中键时, Entercontextmenu
- 右键单击,TabTab...Contextmenu
In Firefox, the click
event is fired for each mouseup
andhitting Enteron a link (or form control). The contextmenu
event is required, because the click
event fires too late for this case.
在Firefox中,click
事件被触发为每个mouseup
和击球Enter上的链接(或表单控件)。该contextmenu
事件是必需的,因为click
对于这种情况,该事件触发得太晚了。
Based on data-URIs and split-second time-outs:
When the click
event is triggered, the href
attribute is temporarily replaced with a data-URI. The event finished, and the default behaviour occurs: Opening the data-URI, dependent on the target
attribute and SHIFT/CTRL modifiers.
Meanwhile, the href
attribute is restored to its original state.
基于数据 URI 和分秒超时:
当click
事件被触发时,href
属性被临时替换为数据 URI。事件结束,默认行为发生:打开数据 URI,取决于target
属性和 SHIFT/CTRL 修饰符。
同时,href
属性恢复到原来的状态。
When the contextmenu
event is triggered, the link also changes for a split second.
当contextmenu
事件被触发时,链接也会在一瞬间发生变化。
- The
Open Link in ...
options will open the data-URI. - The
Copy Link location
option refers to the restored, original URI. - ? The
Bookmark
option refers to the data-URI. - ?
Save Link as
points 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-referrer
instead of none
(and I have also seen never
somewhere). 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 contextmenu
event, 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方法的表单。