Você pode determinar se o Chrome está no modo anônimo por meio de um script?

114

É possível determinar se o Google Chrome está no modo anônimo por meio de um script?

Edit: Na verdade, eu quis dizer que é possível por meio de script de usuário, mas as respostas presumem que o JavaScript está sendo executado em uma página da web. Voltei a fazer a pergunta aqui em relação aos scripts de usuário.

RodeoClown
fonte
28
Não seria muito incognitose você pudesse determiná-lo facilmente :)
Aren
E você tem que lembrar que o usuário deve permitir o modo incógnito para o manual de extensão. Por padrão, tudo é verdade.
Mohamed Mansour
@Mohamed: O usuário que tiver que permitir seria eu, então isso não será um problema :)
RodeoClown
1
@PeteAlvin Ou o site pode diminuir o valor detectando incógnito. O site do Boston Globe não exibe seus artigos incógnitos, impedindo o usuário de burlar sua cota de artigos gratuitos. Em geral, prefiro um site que saiba menos sobre mim.
JohnC de

Respostas:

232

Sim. A API FileSystem é desativada no modo de navegação anônima. Verifique https://jsfiddle.net/w49x9f1a/ quando você está ou não no modo de navegação anônima.

Código de amostra:

    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
fonte
19
Esta é a maneira menos hack-ish e deve estar no topo. Limpo e elegante.
Tom Teman
1
@ user2718671 jsfiddle.net/w49x9f1a ainda funciona bem para mim na última versão do Chrome no mac osx. estranho ...
Alok
1
Eu tentei no Chrome. Funciona, mas a lógica está invertida.
Lucas Massuh de
9
Isso vai acabar logo graças a esses commits
blueren
8
falha no Chrome v 77.0.3865.90
Gitesh Purbia
18

Uma maneira é visitar um URL exclusivo e, em seguida, verificar se um link para esse URL é tratado como visitado por CSS.

Você pode ver um exemplo disso em "Detectando incógnito" (link inativo) .

Artigo de pesquisa do mesmo autor para substituir o link Detecção de incógnito acima

Em main.htmladicionar um iframe,

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

, e algum código 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 = '';
}

Em seguida, test.htmlsão carregados no 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: tentar isso no sistema de arquivos pode fazer o Chrome gritar sobre "Javascript não seguro". No entanto, ele funcionará servindo de um servidor da web.

JHurrah
fonte
Isso é muito legal, eu não percebi que o modo incógnito não destaca os links visitados. Isso requer que o usuário clique em um link.
Igor Zevaka
1
Não, não faz, o iframe "clica" no link.
kibibu
40
Na verdade, isso não funciona, pois a maioria dos navegadores não expõe: informações de estilo visitado por meio de javascript. A interface CSS dirá como se o link tivesse a cor não visitada. Esta é uma medida de segurança que está nos navegadores WebKit- e Gecko pelo menos desde 2010. Era para proteger o histórico do usuário (por exemplo, era possível tentar todos os URLs possíveis e enviar os visitados a terceiros. acesso a tokens em urls e quais não).
Timo Tijhof
2
Artigo oficial da Mozilla explicando as mudanças de privacidade relacionadas a :visited: hacks.mozilla.org/2010/03/…
Denilson Sá Maia
18

No Chrome 74+, você pode determinar isso estimando o espaço de armazenamento do sistema de arquivos disponível

Veja o 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
fonte
4
Esta é a resposta certa agora. A resposta aceita deve ser atualizada com isso ou a resposta aceita deve ser alterada. Não descartar a resposta originalmente aceita, pois era a solução correta no momento.
Cruncher
8

Você pode, em JavaScript, ver a resposta de JHurrah . Exceto para não destacar links, todo o modo anônimo não salva o histórico de navegação e cookies. Da página de ajuda do google :

  • As páginas da web que você abre e os arquivos baixados enquanto você está anônimo não são registrados em seus históricos de navegação e download.
  • Todos os novos cookies são excluídos depois que você fecha todas as janelas anônimas que você abriu.

Como você pode ver, as diferenças entre a navegação normal e anônima acontecem depois que você visita a página da web, portanto, não há nada que o navegador comunique ao servidor quando está neste modo.

Você pode ver o que exatamente o seu navegador envia para o servidor usando um dos muitos analisadores de solicitação HTTP, como este aqui . Compare os cabeçalhos entre a sessão normal e anônima e você não verá nenhuma diferença.

Igor Zevaka
fonte
Recentemente, ele desabilitou todas as extensões, exceto aquelas que foram especificamente marcadas pelo usuário como anônimas.
Tiberiu-Ionuț Stan
4

Se você estiver desenvolvendo uma extensão, poderá usar a API de guias para determinar se uma janela / guia está anônima.

Mais informações podem ser encontradas aqui .

Se você está apenas trabalhando com uma página da Web, não é fácil e foi projetado para ser assim. No entanto, notei que todas as tentativas de abrir um banco de dados (window.database) falham quando em incógnito, isso ocorre porque, quando em incógnito, nenhum traço de dados pode ser deixado na máquina do usuário.

Não testei, mas suspeito que todas as chamadas para localStorage também falham.

Kinlan
fonte
3

Isso usa uma promessa de esperar que o código assíncrono defina um sinalizador, para que possamos usá-lo de forma síncrona depois.

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

então nós podemos fazer

if(isIncognito) alert('in incognito');
else alert('not in incognito');
Aljgom
fonte
Isso parece muito interessante e é uma forma de Javascript com a qual não estou familiarizado e parece não ser compatível com meu Netbeans 8.2 IDE no Windows 10. Mas se eu conseguir fazer funcionar, também estou curioso: poderia substituir reject('Check incognito failed')por resolve(false)se quiser isIncognitoser um booleano que só é verdadeiro ou falso? Obrigado.
Ryan
2
Eu vejo Syntax Error: await is a reserved word, e acho que awaitsempre precisa estar dentro de uma asyncfunção. Então, acho que esse código não funciona.
Ryan
1
rejectlevantaria uma exceção se fosse chamada, e um valor não seria retornado, o isIncognitoque sempre seria trueou falsea maneira como o código é escrito. No entanto, você também poderá usar uma 'resolução' lá se quiser que um valor seja retornado. E pode depender de como o ambiente lida com a espera no escopo global? Funciona no console do Chrome no escopo global, mas você pode tentar agrupar tudo (async function() { 'everything here' })();para que seja executado dentro de uma função assíncrona
aljgom
2
Como alternativa, você pode simplesmente salvar a promessa em em isIncognitovez do resultado e executá-la depois em uma função assíncrona: let isIncognito = new Promise( ...etcentão, em outro lugar, você teria uma função como(async function() { if( !(await isIncognito) ) {alert('not incognito') } })();
aljgom
1
Esta resposta é invalidada no Chrome 76+
Cruncher
0

Função rápida de copiar e colar com base na resposta de Alok (observação: isso é assíncrono)

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

uso:

ifIncognito(true,  ()=>{ alert('in incognito') });
// or
ifIncognito(false, ()=>{ alert('not in incognito') });
Aljgom
fonte
isso não está mais funcionando (talvez tenha funcionado no passado)
Alexandru R
2
Acabei de atualizar meu cromo agora e ele ainda funciona. Vejo que você postou o mesmo acima e depois disse que estava enganado, apenas apontando isso para futuros leitores (sinta-se à vontade para deletar seu comentário, irei deletar este se você fizer).
aljgom
0

Aqui está a resposta sugerida escrita em sintaxe ES6 e ligeiramente esclarecida.

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
fonte
0

Aqui, a solução usando promessas

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 como usá-lo:

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

A documentação do modo de navegação anônima diz especificamente que os sites não se comportarão de maneira diferente. Acredito que isso significa que a resposta é não.

Cachorro
fonte
9
Eu sei que esta resposta tem 4 anos, mas recentemente a Netflix implementou o recurso de detecção "incógnito" e isso despertou meu interesse em pesquisar como eles conseguiram isso. Se você visitar a Netflix no anonimato, a netflix não permite a reprodução de vídeos.
ILikeTacos
Verificado <Chrome>: "Erro no modo de navegação anônima Seu navegador parece estar no modo de navegação anônima."
Pete Alvin de
Acho que esse post poderia ser melhorado porque certamente não fala de fatos. Como já está provado com esta resposta, pode-se ver se alguém gostaria de ver se é visitado no modo incógnito ou em um navegador Chrome regular.
FortuneSoldier
@ILikeTacos Sei que seu comentário tem (mais de) quatro anos, mas o Chrome intencionalmente quebrou sua detecção incógnita, então ainda sinto que ganhei nesse aqui.
Cachorro
@Puppy Bem, sim. Mas na verdade não mishravikas.com/articles/2019-07/…
Cruncher