40 votes

Quel est le moyen le plus fiable pour cacher / usurper le référent en JavaScript?

Normalement, le référent est identifiable par le biais de:

  • JavaScript document.referrer
  • Les en-têtes de requête, par exemple PHP $_SERVER['HTTP_REFERER']

J'ai mis en place un Codepad démo qui montre ces propriétés, à des fins de test.

Exigences:

  1. L'original référent doit effectivement être caché, au moins pour tous les événements de la souris.
  2. En charge des navigateurs (au moins Chrome et Firefox).
  3. Stand-alone, sans aucun contenu externe (plug-ins, les bibliothèques, les pages de redirection, ...).
  4. Pas d'effets secondaires: les Liens doivent pas être réécrit, les entrées de l'historique doit être préservé.

La solution sera utilisé pour masquer le référent en suivant un lien d' <a href="url">.


La description exacte des cas d'utilisation

Comme décrit dans cette question sur les Webapps, des liens à Google de Recherche sont modifiés lors d'un clic. Par conséquent,

  1. Google est en mesure de suivre votre comportement de recherche (de la vie privée-- )
  2. La demande de la page est légèrement en retard.
  3. La page ne peut pas suivre votre Google à la requête de recherche (de Confidentialité++ )
  4. Glisser/copier Url ressembler http://google.com/lotsoftrash?url=actualurl.

Je suis le développement d'un Script (Firefox) / le Contenu du script (Chrome) (le code), qui supprime Google lien-mutilante de l'événement. En conséquence, les points 1, 2 et 4 sont traitées.

Le Point 3 de la demeure.

  • Chrome: <a rel="noreferrer">
  • Firefox: data-URIs. J'ai créé une approche plus sophistiquée de mettre en œuvre cette fonctionnalité pour la gauche - et moyen-clics, tout en continuant de l'application du point 4. Cependant, j'ai du mal avec le bouton droit sur la méthode.

40voto

Rob W Points 125904

J'ai trouvé une solution qui fonctionne dans Chrome et Firefox. J'ai mis en place le code dans un Script, de Ne pas suivre moi Google.

Démo (testé dans Firefox 9 et Chrome 17): http://jsfiddle.net/RxHw5/

Référent de la clandestinité pour Webkit (Chrome, ..)

Basé sur Webkit navigateurs (google Chrome, Safari) appuyer <a rel="noreferrer">spec.
Référent de masquage peut être pleinement mises en œuvre en combinant cette méthode avec deux écouteurs d'événement:

  • mousedown - Sur un clic, clic milieu, cliquez-droit sur contextmenu, ...
  • keydown (Onglet Onglet Onglet ... Entrez).

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

Référent de la clandestinité pour Firefox

Malheureusement, Firefox n'a pas (encore) de soutien rel="noreferrer"[bug 530396].

Un data-URI + <meta http-equiv=refresh> peut être utilisé pour masquer le référent dans Firefox et IE). La mise en œuvre de cette fonctionnalité est plus compliqué, mais nécessite également de deux événements:

  • click - Sur un clic, sur le moyen-cliquez, Entrez
  • contextmenu - Sur clic droit, Onglet Onglet ... Contextmenu

Dans Firefox, l' click événement est déclenché pour chaque mouseup et de frapper d' Entrée sur un lien (ou contrôle de formulaire). L' contextmenu événement est nécessaire, parce que l' click événement se déclenche trop tard pour ce cas.

Basé sur des données d'Uri et en une fraction de seconde délais d'attente:
Lorsque l' click événement est déclenché, l' href attribut est temporairement remplacé par un data-URI. L'événement terminé, et le comportement par défaut se produit: l'Ouverture de la data-URI, dépend de l' target d'attribut et SHIFT/CTRL modificateurs.
Pendant ce temps, l' href attribut est restauré à son état d'origine.

Lorsque l' contextmenu événement est déclenché, le lien change également pour une fraction de seconde.

  • L' Open Link in ... options ouvrir le data-URI.
  • L' Copy Link location option fait référence à la restauration, URI originale.
  • ☹ L' Bookmark option fait référence à la data-URI.
  • Save Link as de points à la data-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);

Joindre les deux méthodes

J'ai créé un Script pour Chrome et Firefox. Le script a besoin d'une méthode efficace pour déterminer le référent de masquage méthode doit être utilisée. Pour obtenir cela, j'ai vérifié pour la validité d'un webkit propriété CSS:

var isWebkit = document.createElement("a");
isWebkit.style.cssText = "-webkit-border-radius:1px;";
isWebkit = isWebkit.style.cssText.indexOf("radius") !== -1;
// Later: if (isWebkit) { /* Webkit-specific code */ } else { /* Other method */}

10voto

fmsf Points 13399

Ne pouvez-vous pas créer un système de liaison qui réside dans les iframes?

Si vous enroulez un iframe autour de chaque lien, l’iframe peut servir de référence externe. L'utilisateur clique sur le lien à l'intérieur du cadre pour ouvrir une page dont le référent est défini sur l'emplacement de l'iFrame au lieu de la page réelle.

3voto

jpgerek Points 167

Il existe une solution multi-navigateur en Javascript qui supprime le référent, elle utilise des iframes créés de manière dynamique, vous pouvez jeter un coup d'œil à une preuve de concept (disclaimer: il utilise un peu de la bibliothèque JS que j'ai écrite).

1voto

Boldewyn Points 29961

C'est plus compliqué qu'il n'y paraît à première vue. Regardez le code de ce projet:

https://github.com/knu/noreferrer

Il promet tout à fait ce que vous voulez, mais vous devez le faire sur la page de liens.

1voto

Pumbaa80 Points 27066

Ce que vous demandez ne peut pas être fait dans Firefox.

Le contexte actuel de menu mise en œuvre passe toujours le document actuel en tant que référent:

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

Évidemment, userscripts ne sont pas autorisés à modifier le menu contextuel de la mise en œuvre, de sorte que le seul moyen de sortir est une extension de navigateur.

(Ou, ce qui serait une assez mauvaise hack, désactiver le menu contextuel en appelant preventDefault() sur le contextmenu événement, et d'utiliser votre propre menu contextuel personnalisé)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X