Puoi determinare se Chrome è in modalità di navigazione in incognito tramite uno script?


114

È possibile determinare se Google Chrome è in modalità di navigazione in incognito tramite uno script?

Modifica: in realtà volevo dire che è possibile tramite script utente, ma le risposte presumono che JavaScript sia in esecuzione su una pagina web. Ho posto nuovamente la domanda qui riguardo agli script utente.


28
Non sarebbe molto incognitose potessi determinarlo facilmente :)
Aren

E devi ricordare che l'utente deve consentire la modalità di navigazione in incognito per il manuale dell'estensione. Per impostazione predefinita, tutto è vero.
Mohamed Mansour

@ Mohamed: L'utente che lo deve consentire sarei io, quindi non sarà un problema :)
RodeoClown


1
@PeteAlvin Oppure il sito potrebbe diminuire il valore rilevando la navigazione in incognito. Il sito di Boston Globe non visualizzerà i suoi articoli in incognito, impedendo all'utente di aggirare la propria quota di articoli gratuiti. In generale, preferisco un sito che sappia meno di me.
JohnC

Risposte:


232

Sì. L'API FileSystem è disabilitata in modalità di navigazione in incognito. Dai un'occhiata a https://jsfiddle.net/w49x9f1a/ quando sei e non sei in modalità di navigazione in incognito.

Codice di esempio:

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


19
Questo è il modo meno hacker e dovrebbe essere al top. Pulito ed elegante.
Tom Teman

1
@ user2718671 jsfiddle.net/w49x9f1a funziona ancora bene per me nell'ultimo Chrome su mac osx. strano ...
Alok

1
Ho provato a Chrome. Funziona, ma la logica è al contrario.
Lucas Massuh

9
Questo presto
sparirà

8
fail in chrome v 77.0.3865.90
Gitesh Purbia

18

Un modo è visitare un URL univoco e quindi verificare se un collegamento a tale URL viene considerato come visitato da CSS.

Puoi vedere un esempio di questo in "Rilevamento di navigazione in incognito" (Dead link) .

Documento di ricerca dello stesso autore per sostituire il collegamento di rilevamento in incognito sopra

In main.htmlaggiungi un iframe,

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

e un po 'di codice 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 = '';
}

Quindi in test.htmlquello vengono caricati nell'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> 

NOTA: provare questo dal filesystem può far piangere Chrome su "Javascript non sicuro". Tuttavia, funzionerà servendo da un server web.


È abbastanza interessante, non mi ero reso conto che la modalità di navigazione in incognito non evidenzia i collegamenti visitati. Tuttavia, ciò richiede all'utente di fare clic su un collegamento.
Igor Zevaka

1
No, l'iframe "fa clic" sul collegamento.
kibibu

40
Questo in realtà non funziona poiché la maggior parte dei browser non espone: informazioni sullo stile visitate tramite javascript. L'interfaccia CSS dirà come se il collegamento avesse il colore non visitato. Questa è una misura di sicurezza presente nei browser WebKit e Gecko almeno dal 2010. Questo serviva a proteggere la cronologia dell'utente (ad esempio, si potevano provare tutti gli URL possibili e inviare quelli visitati a terzi. In questo modo si poteva ottenere accesso ai token negli URL e cosa no).
Timo Tijhof

2
Articolo ufficiale di Mozilla che spiega le modifiche alla privacy relative a :visited: hacks.mozilla.org/2010/03/…
Denilson Sá Maia,

18

In Chrome 74+ puoi determinarlo stimando lo spazio di archiviazione del file system disponibile

Vedi il 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')
}

4
Questa è la risposta giusta adesso. O la risposta accettata dovrebbe essere aggiornata con questa, oppure la risposta accettata dovrebbe cambiare. Non per togliere la risposta originariamente accettata poiché era la soluzione corretta al momento.
Cruncher

8

Puoi, in JavaScript, vedere la risposta di JHurrah . Ad eccezione di non evidenziare i collegamenti, tutta la modalità di navigazione in incognito non salva la cronologia di navigazione e i cookie. Dalla pagina della guida di Google :

  • Le pagine web che apri e i file scaricati durante la navigazione in incognito non vengono registrati nelle cronologie di navigazione e download.
  • Tutti i nuovi cookie vengono eliminati dopo aver chiuso tutte le finestre di navigazione in incognito che hai aperto.

Come puoi vedere, le differenze tra la normale navigazione e la navigazione in incognito si verificano dopo aver visitato la pagina web, quindi non c'è nulla che il browser comunichi al server quando è in questa modalità.

Puoi vedere cosa invia esattamente il tuo browser al server utilizzando uno dei tanti analizzatori di richieste HTTP, come questo qui . Confronta le intestazioni tra la sessione normale e quella in incognito e non vedrai alcuna differenza.


Di recente, disabilita tutte le estensioni tranne quelle specificatamente contrassegnate dall'utente come sicure in incognito.
Tiberiu-Ionuț Stan

4

Se stai sviluppando un'estensione, puoi utilizzare l'API delle schede per determinare se una finestra / scheda in incognito.

Ulteriori informazioni possono essere trovate qui .

Se stai solo lavorando con una pagina web, non è facile ed è progettato per essere così. Tuttavia, ho notato che tutti i tentativi di aprire un database (window.database) falliscono quando in incongnito, questo perché quando in incognito non è consentita alcuna traccia di dati sulla macchina dell'utente.

Non l'ho testato ma sospetto che anche tutte le chiamate a localStorage falliscano.


3

Questo utilizza una promessa di attendere che il codice asincrono imposti un flag, in modo che possiamo usarlo in modo sincrono in seguito.

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

allora possiamo fare

if(isIncognito) alert('in incognito');
else alert('not in incognito');

Sembra molto interessante ed è una forma di Javascript con cui non ho familiarità e non sembra supportata dal mio IDE Netbeans 8.2 in Windows 10. Ma se riesco a farlo funzionare, sono anche curioso: potrei sostituirlo reject('Check incognito failed')con resolve(false)se voglio isIncognitoessere un booleano che è sempre e solo vero o falso? Grazie.
Ryan

2
Capisco Syntax Error: await is a reserved word, e penso che awaitdebba essere sempre all'interno di una asyncfunzione. Quindi penso che questo codice non funzioni.
Ryan

1
rejectsolleverebbe un'eccezione se viene chiamato e un valore non sarebbe restituito, così isIncognitosarebbe sempre trueo falseil modo in cui il codice è scritto. Tuttavia, potresti anche utilizzare una "risoluzione" se desideri restituire un valore. E potrebbe dipendere da come l'ambiente gestisce l'attesa nell'ambito globale? Funziona sulla console Chrome nell'ambito globale, ma potresti provare a avvolgere tutto in (async function() { 'everything here' })();modo che venga eseguito all'interno di una funzione asincrona
aljgom

2
In alternativa, potresti semplicemente salvare la promessa al isIncognitoposto del risultato ed eseguirla in seguito in una funzione asincrona: let isIncognito = new Promise( ...etcquindi da qualche altra parte avresti una funzione come(async function() { if( !(await isIncognito) ) {alert('not incognito') } })();
aljgom

1
Questa risposta non è valida in chrome 76+
Cruncher

0

Funzione copia-incolla rapida basata sulla risposta di Alok (nota: questa è asincrona)

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, ()=>{});
    }
} 

utilizzo:

ifIncognito(true,  ()=>{ alert('in incognito') });
// or
ifIncognito(false, ()=>{ alert('not in incognito') });

questo non funziona più (forse ha funzionato in passato)
Alexandru R

2
Ho appena aggiornato il mio Chrome ora e funziona ancora. Vedo che hai postato lo stesso sopra e poi hai detto che ti sbagliavi, facendolo notare ai futuri spettatori (sentiti libero di cancellare il tuo commento, cancellerò questo se lo fai).
aljgom

0

Ecco la risposta suggerita scritta con la sintassi ES6 e leggermente pulita.

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)

0

Ecco la soluzione usando le promesse

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

E come usarlo:

isIncognito().then(yes => console.log(yes)).catch(isnot => console.log(isnot))

-10

La documentazione per la modalità di navigazione in incognito afferma specificamente che i siti Web non si comporteranno in modo diverso. Credo che questo significhi che la risposta è no.


9
So che questa risposta risale a 4 anni fa, ma recentemente Netflix ha implementato la funzione di rilevamento "in incognito" e questo ha suscitato il mio interesse per la ricerca di come ottenerlo. Se visiti Netflix in incognito, netflix non ti consente di riprodurre video.
ILikeTacos

Verificato <Chrome>: "Errore modalità di navigazione in incognito Il tuo browser sembra essere in modalità di navigazione in incognito."
Pete Alvin

Penso che questo post potrebbe essere migliorato perché di certo non parla di fatti. Come è già stato dimostrato sia su che giù da questa risposta, si può vedere se qualcuno vorrebbe vedere se viene visitato dalla modalità di navigazione in incognito o da un normale browser Chrome.
FortuneSoldier

@ILikeTacos So che il tuo commento ha (più di) quattro anni, ma Chrome ha intenzionalmente interrotto il rilevamento in incognito, quindi sento ancora di aver vinto su quello ..
Puppy

@ Cucciolo Ebbene sì. Ma in realtà non mishravikas.com/articles/2019-07/…
Cruncher
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.