Каков самый надежный способ скрыть / обмануть реферера в JavaScript?
обычно реферер отслеживается через:
- в JavaScript!--0-->
- заголовки запросов, например PHP
$_SERVER['HTTP_REFERER']
Я создал подсветка демо, который показывает эти свойства, для целей тестирования.
требования:
- исходный реферер должен быть эффективно скрыт, по крайней мере, для всех событий мыши.
- Кросс-браузерная поддержка (в минимум Chrome и Firefox).
- автономный, без какого-либо внешнего контента (Плагины, библиотеки, страницы перенаправления, ...).
- никаких побочных эффектов: ссылки должны не быть переписаны, записи истории должны быть сохранил.
решение будет использоваться для скрытия реферера при переходе по ссылке из <a href="url">
.
точное описание использования
как описано в этот вопрос по Webapps, ссылки в Google Search изменяются по щелчку мыши. Следовательно,
- Google может отслеживать ваше поведение (конфиденциальность-- )
- запрос страницы немного задерживается.
- связанная страница не может отслеживать ваш поисковый запрос Google (конфиденциальность++ )
- Перетаскиваемые / скопированные URL-адреса выглядят как
http://google.com/lotsoftrash?url=actualurl
.
Я разрабатываю Userscript (Firefox) / скрипт контента (Chrome) (код), который удаляет событие искажения ссылок Google. В результате рассматриваются пункты 1, 2 и 4.
пункт 3 остается.
- Chrome:
<a rel="noreferrer">
- Firefox:
data-URIs
. Я создал сложный подход для реализации этой функции для левого и среднего кликов, все еще применяя точку 4. тем не менее, я борюсь с правой кнопкой мыши метод.
10 ответов
я нашел решение, которое работает в Chrome и Firefox. Я реализовал код в Userscript,не отслеживать меня Google.
Demo (протестировано в Firefox 9 и Chrome 17): http://jsfiddle.net/RxHw5/
скрытие реферера для Webkit (Chrome, ..) и Firefox 37+ (33+*)
браузеры на основе Webkit (такие как Chrome, Safari) поддержка <a rel="noreferrer">
spec.
Скрытие реферера может быть полностью реализовано путем объединения этого метода с двумя прослушивателями событий:
-
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);
* rel=noreferrer
поддерживается в Firefox с 33, но поддержка была ограничена ссылками на странице. Рефереры все еще отправлялись, когда пользователь открывал вкладку через контекстное меню. Эта ошибка была исправлена в Firefox 37 [ошибка 1031264].
реферер скрывается для старых версий Firefox
Firefox не поддерживает rel="noreferrer"
до версии 33 `[530396 ошибка] (или 37, Если вы хотите скрыть реферер для контекстных меню также).
"данные" -Ури + <meta http-equiv=refresh>
может использоваться для скрытия реферера в Firefox (и IE). Реализация этой функции более сложна, но также требует двух событий:
-
click
- по клику, по среднему клику, Enter
-
contextmenu
-при щелчке правой кнопкой мыши,Tab Tab ... Contextmenu
в Firefox click
событие для каждого mouseup
и удара Enter по ссылке (или форма контроля). The contextmenu
событие нужно, ведь click
событие срабатывает слишком поздно для этого случая.
на основе данных-URIs и split-second тайм-аутов:
Когда 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-sniffing), или используйте один из запутанных методов обнаружения от как я могу обнаружить поддержку rel="noreferrer"?.
не можете ли вы создать систему ссылок, которая находится внутри iframes?
Если вы обертываете 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 есть кросс-браузерное решение, которое удаляет реферер, он использует iframes, созданные динамически, вы можете взглянуть на доказательство концепции (отказ от ответственности: он использует небольшую библиотеку JS, которую я написал ).
можно использовать тег стандартный проект политики реферера чтобы предотвратить отправку заголовка referer в источник запроса. Пример:
<meta name="referrer" content="none">
хотя Chrome и Firefox уже реализовали черновую версию политики реферера, вы должны быть осторожны с ней, потому что, например, Chrome ожидает no-referrer
вместо none
(и я также видел never
где-то). Я не знаю поведения, если вы просто добавляете три отдельных мета-тега, но в случае, если это не работает, вы все равно можете просто реализовать короткий скрипт, который повторяет все три значения и проверяет, действительно ли значение было установлено после установки атрибута/свойства мета-тега.
этот мета-тег применяется ко всем запросам на текущей странице (ajax, изображения, скрипты, другие ресурсы...) и переход на другую страницу.
Это сложнее, чем может показаться на первый взгляд. Посмотрите на код этого проекта:
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 // <----------------
});
},
очевидно, что userscripts не разрешено изменять реализацию контекстного меню, поэтому единственным выходом является расширение браузера.
(или, что было бы довольно плохим взломом, отключите контекстное меню, вызвав preventDefault()
на contextmenu
событие и используйте свой собственный контекст меню)
очень полный (но короткий) анализ можно найти по адресу:
http://lincolnloop.com/blog/2012/jun/27/referrer-blocking-hard/
в этой статье анализируются оба метода, объясненные в других ответах (метод js, перенаправление iframe), и, наконец, предлагают опосредованный подход к странице перенаправления, подобный тому, который наблюдается в ссылках поиска google.
я реализовал простое, но эффективное решение iframe с использованием jquery.
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()
в основном мы представляем форму с желаемым действие метод.