Pouvez-vous déterminer si Chrome est en mode navigation privée via un script?

114

Est-il possible de déterminer si Google Chrome est en mode navigation privée via un script?

Edit: Je voulais en fait dire est-ce possible via un script utilisateur, mais les réponses supposent que JavaScript s'exécute sur une page Web. J'ai re-posé la question ici en ce qui concerne les scripts utilisateur.

RodéoClown
la source
28
Ce ne serait pas très bien incognitosi vous pouviez le déterminer facilement :)
Aren
Et vous devez vous rappeler que l'utilisateur doit autoriser le mode navigation privée pour le manuel de l'extension. Par défaut, tout est vrai.
Mohamed Mansour
@Mohamed: L'utilisateur devant l'autoriser serait moi, donc ce ne sera pas un problème :)
RodeoClown
1
@PeteAlvin Ou le site pourrait nuire à la valeur en détectant la navigation privée. Le site de Boston Globe n'affichera pas ses articles en mode incognito, empêchant l'utilisateur de contourner son quota d'articles gratuits. En général, je préfère un site en savoir moins sur moi.
JohnC

Réponses:

232

Oui. L'API FileSystem est désactivée en mode navigation privée. Consultez https://jsfiddle.net/w49x9f1a/ lorsque vous êtes et n'êtes pas en mode navigation privée.

Exemple de code:

    var fs = window.RequestFileSystem || window.webkitRequestFileSystem;
    if (!fs) {
      console.log("check failed?");
    } else {
      fs(window.TEMPORARY,
         100,
         console.log.bind(console, "not in incognito mode"),
         console.log.bind(console, "incognito mode"));
    }

Alok
la source
19
C'est la manière la moins hack-ish et devrait être au sommet. Propre et élégant.
Tom Teman
1
@ user2718671 jsfiddle.net/w49x9f1a fonctionne toujours très bien pour moi dans le dernier Chrome sur mac osx. bizarre ...
Alok
1
J'ai essayé Chrome. Cela fonctionne, mais la logique est à l'envers.
Lucas Massuh
9
Cela va bientôt disparaître grâce à ces commits
blueren
8
échouer dans chrome v 77.0.3865.90
Gitesh Purbia
18

Une façon est de visiter une URL unique, puis de vérifier si un lien vers cette URL est traité comme visité par CSS.

Vous pouvez voir un exemple de ceci dans "Détecter Incognito" (lien mort) .

Document de recherche du même auteur pour remplacer le lien Détecter la navigation privée ci-dessus

En main.htmlajoutant un iframe,

 <iframe id='testFrame' name='testFrame' onload='setUniqueSource(this)' src='' style="width:0; height:0; visibility:hidden;"></iframe>

, et du code JavaScript:

function checkResult() {
  var a = frames[0].document.getElementById('test');
  if (!a) return;

  var color;
  if (a.currentStyle) {
    color = a.currentStyle.color;
  } else {
    color = frames[0].getComputedStyle(a, '').color;
  }

  var visited = (color == 'rgb(51, 102, 160)' || color == '#3366a0');
  alert('mode is ' + (visited ? 'NOT Private' : 'Private'));
}

function setUniqueSource(frame) {
  frame.src = "test.html?" + Math.random();
  frame.onload = '';
}

Ensuite test.html, ils sont chargés dans l'iFrame:

<style> 
   a:link { color: #336699; }
   a:visited { color: #3366A0; }
</style> 
<script> 
  setTimeout(function() {
    var a = document.createElement('a');
    a.href = location;
    a.id = 'test';
    document.body.appendChild(a);
    parent.checkResult();
  }, 100);
</script> 

REMARQUE: essayer ceci à partir du système de fichiers peut faire pleurer Chrome à propos de "Javascript non sécurisé". Il fonctionnera cependant à partir d'un serveur Web.

JHurrah
la source
C'est plutôt cool, je ne savais pas que le mode incognito ne mettait pas en évidence les liens visités. Cela oblige l'utilisateur à cliquer sur un lien.
Igor Zevaka
1
Non, ce n'est pas le cas, l'iframe "clique" sur le lien.
kibibu
40
Cela ne fonctionne pas car la plupart des navigateurs n'exposent pas: les informations de style visitées via javascript. L'interface CSS dira comme si le lien avait la couleur non visitée. Il s'agit d'une mesure de sécurité qui existe dans les navigateurs WebKit et Gecko au moins depuis 2010. Il s'agissait de protéger l'historique de l'utilisateur (par exemple, on pouvait essayer toutes les URL possibles et envoyer les URL visitées à un tiers. De cette façon, on pouvait obtenir accès aux jetons dans les URL et autres).
Timo Tijhof du
2
Article officiel de Mozilla expliquant les changements de confidentialité concernant :visited: hacks.mozilla.org/2010/03/…
Denilson Sá Maia
18

Dans Chrome 74+, vous pouvez le déterminer en estimant l'espace de stockage disponible du système de fichiers

Voir le jsfiddle

if ('storage' in navigator && 'estimate' in navigator.storage) {
    const {usage, quota} = await navigator.storage.estimate();
    console.log(`Using ${usage} out of ${quota} bytes.`);

    if(quota < 120000000){
        console.log('Incognito')
    } else {
        console.log('Not Incognito')
    }   
} else {
    console.log('Can not detect')
}
Vinnie James
la source
4
C'est la bonne réponse maintenant. Soit la réponse acceptée doit être mise à jour avec ceci, soit la réponse acceptée doit changer. Ne pas enlever la réponse initialement acceptée car c'était la bonne solution à l'époque.
Cruncher
8

Vous pouvez, en JavaScript, voir la réponse de JHurrah . Sauf pour ne pas mettre en évidence les liens, tout le mode de navigation privée ne sauvegarde pas l'historique de navigation et les cookies. Depuis la page d'aide Google :

  • Les pages Web que vous ouvrez et les fichiers téléchargés lorsque vous êtes en mode navigation privée ne sont pas enregistrés dans votre historique de navigation et de téléchargement.
  • Tous les nouveaux cookies sont supprimés après la fermeture de toutes les fenêtres de navigation privée que vous avez ouvertes.

Comme vous pouvez le voir, les différences entre la navigation normale et la navigation privée se produisent après la visite de la page Web, il n'y a donc rien que le navigateur communique au serveur lorsqu'il est dans ce mode.

Vous pouvez voir exactement ce que votre navigateur envoie au serveur en utilisant l'un des nombreux analyseurs de requêtes HTTP, comme celui-ci ici . Comparez les en-têtes entre la session normale et la navigation privée et vous ne verrez aucune différence.

Igor Zevaka
la source
Récemment, il désactive toutes les extensions à l'exception des extensions qui ont été spécifiquement marquées par l'utilisateur comme étant protégées par navigation privée.
Tiberiu-Ionuț Stan
4

Si vous développez une extension, vous pouvez utiliser l'API des onglets pour déterminer si une fenêtre / un onglet est incognito.

Plus d'informations peuvent être trouvées ici .

Si vous travaillez simplement avec une page Web, ce n'est pas facile et c'est conçu pour être ainsi. Cependant, j'ai remarqué que toutes les tentatives d'ouverture d'une base de données (window.database) échouent en mode incongnito, c'est parce qu'en mode incognito, aucune trace de données n'est autorisée sur la machine des utilisateurs.

Je ne l'ai pas testé mais je soupçonne que tous les appels à localStorage échouent également.

Kinlan
la source
3

Cela utilise une promesse d'attendre que le code asynchrone définisse un indicateur, afin que nous puissions l'utiliser de manière synchrone par la suite.

let isIncognito = await new Promise((resolve, reject)=>{
    var fs = window.RequestFileSystem || window.webkitRequestFileSystem;
    if (!fs) reject('Check incognito failed');
    else fs(window.TEMPORARY, 100, ()=>resolve(false), ()=>resolve(true));      
});

alors nous pouvons faire

if(isIncognito) alert('in incognito');
else alert('not in incognito');
aljgom
la source
Cela semble très intéressant et est une forme de Javascript que je ne suis pas familier avec et semble non pris en charge par mon Netbeans 8.2 IDE dans Windows 10. Mais si je peux le faire au travail, je suis aussi curieuse: pourrais - je remplacer reject('Check incognito failed')avec resolve(false)si je veux isIncognitoêtre un booléen qui n'est jamais vrai ou faux? Merci.
Ryan
2
Je vois Syntax Error: await is a reserved word, et je pense qu'il awaitfaut toujours être dans une asyncfonction. Donc je pense que ce code ne fonctionne pas.
Ryan
1
rejectsoulèverait une exception si elle est appelée, et une valeur ne serait pas retourné, donc isIncognitoserait toujours trueou falsela façon dont le code est écrit. Cependant, vous pourrez également y utiliser une «résolution» si vous souhaitez qu'une valeur soit renvoyée. Et cela pourrait dépendre de la manière dont l'environnement gère l'attente dans la portée globale? Cela fonctionne sur la console Chrome dans la portée globale, mais vous pouvez essayer de tout emballer (async function() { 'everything here' })();pour qu'il soit exécuté dans une fonction asynchrone
aljgom
2
Alternativement, vous pouvez simplement enregistrer la promesse au isIncognitolieu du résultat, et l'exécuter ensuite dans une fonction asynchrone: let isIncognito = new Promise( ...etcpuis ailleurs, vous auriez une fonction comme(async function() { if( !(await isIncognito) ) {alert('not incognito') } })();
aljgom
1
Cette réponse est invalidée en chrome 76+
Cruncher
0

Fonction de copier-coller rapide basée sur la réponse d'Alok (note: c'est asynchrone)

function ifIncognito(incog,func){
    var fs = window.RequestFileSystem || window.webkitRequestFileSystem;
    if (!fs)  console.log("checking incognito failed");
    else {
        if(incog) fs(window.TEMPORARY, 100, ()=>{}, func);
        else      fs(window.TEMPORARY, 100, func, ()=>{});
    }
} 

usage:

ifIncognito(true,  ()=>{ alert('in incognito') });
// or
ifIncognito(false, ()=>{ alert('not in incognito') });
aljgom
la source
cela ne fonctionne plus (peut-être que cela a fonctionné dans le passé)
Alexandru R
2
Je viens de mettre à jour mon chrome maintenant et cela fonctionne toujours. Je vois que vous avez posté la même chose ci-dessus et que vous avez ensuite dit que vous vous trompiez, en le signalant simplement aux futurs téléspectateurs (n'hésitez pas à supprimer votre commentaire, je supprimerai celui-ci si vous le faites).
aljgom
0

Voici la réponse suggérée écrite dans la syntaxe ES6 et légèrement nettoyée.

const isIncognito = () => new Promise((resolve, reject) => {
    const fs = window.RequestFileSystem || window.webkitRequestFileSystem;

    if (!fs) {
        reject('Cant determine whether browser is running in incognito mode!');
    }

    fs(window.TEMPORARY, 100, resolve.bind(null, false), resolve.bind(null, true));
});

// Usage
isIncognito()
    .then(console.log)
    .catch(console.error)
Nikksan
la source
0

Voici la solution utilisant les promesses

const isIncognito = () => {
    return new Promise((resolve, reject) => {
      if ("storage" in navigator && "estimate" in navigator.storage) {
        navigator.storage.estimate().then((res) => {
          console.log(`Using ${res.usage} out of ${res.quota} bytes.`);
          if (res.quota < 120000000) {
            resolve(true);
          } else {
            reject(false);
          }
        });
      } else {
        reject(false);
      }
    });
  };

Un comment l'utiliser:

isIncognito().then(yes => console.log(yes)).catch(isnot => console.log(isnot))
Juan Ricardo
la source
-10

La documentation du mode navigation privée indique spécifiquement que les sites Web ne se comporteront pas différemment. Je crois que cela signifie que la réponse est non.

Chiot
la source
9
Je sais que cette réponse a 4 ans, mais récemment Netflix a implémenté la détection "incognito" en vedette, et cela a piqué mon intérêt pour rechercher comment ils y parviennent. Si vous visitez Netflix en mode incognito, netflix ne vous permet pas de lire des vidéos.
ILikeTacos
Vérifié <Chrome>: "Erreur de mode de navigation privée Votre navigateur semble être en mode de navigation privée."
Pete Alvin
Je pense que cet article pourrait être amélioré car il ne parle certainement pas de faits. Comme il est déjà prouvé à la fois de haut en bas à partir de cette réponse, on peut voir si quelqu'un souhaite voir s'il est visité en mode incognito ou à partir d'un navigateur Chrome ordinaire.
FortuneSoldier
@ILikeTacos Je sais que votre commentaire a (plus de) quatre ans, mais Chrome a intentionnellement brisé leur détection incognito, donc j'ai toujours l'impression que j'ai gagné sur celui-là ..
Puppy
@Puppy Eh bien oui. Mais en réalité , pas mishravikas.com/articles/2019-07/...
Cruncher