簡體   English   中英

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

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

通常,引薦來源可追溯到:

  • JavaScript的document.referrer
  • 請求標頭,例如PHP的$_SERVER['HTTP_REFERER']

我已經設置了一個Codepad演示 ,它顯示了這些屬性,用於測試目的。

要求:

  1. 應該有效地隱藏原始引用者,至少對於所有鼠標事件都是如此。
  2. 跨瀏覽器支持(至少Chrome和Firefox)。
  3. 獨立,沒有任何外部內容(插件,庫,重定向頁面......)。
  4. 無副作用:鏈接不應被改寫,歷史記錄項應予以保留

在關注<a href="url">鏈接時,該解決方案將用於隱藏引薦來源。


用例的確切描述

在Webapps上的此問題中所述,Google搜索中的鏈接會在點擊時進行修改。 所以,

  1. Google可以跟蹤您的搜索行為(隱私 - )
  2. 頁面請求稍有延遲。
  3. 鏈接的網頁無法跟蹤您的Google搜索查詢(隱私++)
  4. 拖動/復制的網址類似於http://google.com/lotsoftrash?url=actualurl

我正在開發一個用戶腳本(Firefox)/內容腳本(Chrome) 代碼 ,它刪除了Google的鏈接殘缺事件。 結果,處理了第1,2和4點。

第3點仍然存在。

  • Chrome: <a rel="noreferrer">
  • Firefox: data-URIs 我已經創建了一種復雜的方法來實現左鍵和中鍵的這個功能,同時仍然執行第4點。 但是,我正在努力使用右鍵單擊方法。

我找到了一個適用於Chrome和Firefox的解決方案。 我在用戶腳本中實現了代碼, 不要跟蹤我谷歌

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

推薦人隱藏Webkit(Chrome,..)和Firefox 37+(33 + *)

基於Webkit的瀏覽器(如Chrome,Safari) 支持 <a rel="noreferrer"> 規范
通過將此方法與兩個事件偵聽器組合,可以完全實現Referrer隱藏:

  • mousedown - 單擊,中鍵單擊,右鍵單擊contextmenu,...
  • keydownTab Tab Tab ... 輸入 )。

碼:

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

*自33以來,Firefox支持rel=noreferrer ,但支持僅限於頁內鏈接。 當用戶通過上下文菜單打開選項卡時,仍會發送引薦來源。 此錯誤已在Firefox 37中修復 [ bug 1031264 ]

引用者隱藏舊版Firefox

Firefox不支持rel="noreferrer"直到版本33` [ bug 530396 ] (或37,如果你想隱藏上下文菜單的引用者)。

可以使用data-URI + <meta http-equiv=refresh>來隱藏Firefox(和IE)中的引用者。 實現此功能更復雜,但也需要兩個事件:

  • click - 單擊,中鍵單擊, 回車
  • contextmenu - 右鍵單擊​​, Tab Tab ... Contextmenu

在Firefox中, click事件被激發每個mouseup 鏈接(或表單控件),按下回車鍵 contextmenu事件是必需的,因為click事件對於這種情況觸發得太晚。

基於數據URI和瞬間超時:
觸發click事件時, href屬性會暫時替換為data-URI。 事件結束,並發生默認行為:打開data-URI,具體取決於target屬性和SHIFT / CTRL修飾符。
同時, href屬性恢復到其原始狀態。

觸發contextmenu事件時,鏈接也會contextmenu更改。

  • Open Link in ...選項將打開data-URI。
  • Copy Link location選項指的是已還原的原始URI。
  • Bookmark選項指的是數據URI。
  • Save Link as數據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-sniffing),或者使用其中一種來自如何檢測rel =“noreferrer”支持的復雜檢測方法

你不能創建一個駐留在iframe中的鏈接系統嗎?

如果圍繞每個鏈接包裝iframe,則iframe可以充當外部取消引用。 用戶可以單擊框架內的鏈接,打開其引用者設置為iFrame位置的頁面,而不是實際頁面。

根據要求,使用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標頭的方法。

Javascript中有一個跨瀏覽器解決方案,它刪除了引用者,它使用動態創建的iframe,你可以看一看概念證明 (免責聲明:它使用了我寫的一點JS庫)。

您可以使用新的Referrer Policy標准草案來防止將referer標頭發送到請求源。 例:

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

雖然Chrome和Firefox已經實現了推薦人政策的草案版本,但您應該小心謹慎,因為例如Chrome期望no-referrer而不是none (我也never見過某個地方)。 如果您只添加三個單獨的元標記,我不知道該行為,但是如果不起作用,您仍然可以只實現一個短腳本,該腳本迭代所有三個值並檢查在設置屬性后是否確實設置了值元標記的屬性。

此元標記適用於當前頁面上的所有請求(ajax,圖像,腳本,其他資源...)和導航到另一個頁面。

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

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

本文分析了在其他答案(js方法,iframe重定向)中解釋的兩種方法,最后提出了一個中介重定向頁面方法,就像在谷歌搜索鏈接中看到的那樣。

這比第一眼看上去更棘手。 看看這個項目的代碼:

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

顯然,不允許用戶腳本更改上下文菜單實現,因此唯一的出路是瀏覽器擴展。

(或者,這將是一個非常糟糕的黑客,通過在contextmenu事件上調用preventDefault()來禁用上下文菜單,並使用您自己的自定義上下文菜單)

我使用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);

如果我們使用JavaScript提交FORM,這樣就沒有引用者了。

document.form_name.submit()

基本上我們提交一個帶有所需ACTION方法的表格。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM