Можете ли вы определить, находится ли Chrome в режиме инкогнито с помощью сценария?

Можно ли с помощью скрипта определить, находится ли Google Chrome в режиме инкогнито?

Изменить: Я на самом деле имел в виду, возможно ли это через пользовательский скрипт, но ответы предполагают, что JavaScript работает на веб-странице. Я переспросил вопрос здесь относительно пользовательских сценариев.

13 ответов

Решение

Да. FileSystem API отключен в режиме инкогнито. Проверьте http://jsfiddle.net/w49x9f1a/ когда вы находитесь и не находитесь в режиме инкогнито.

Образец кода:

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

В Chrome 74+ это можно определить, оценив доступное пространство для хранения файловой системы.

См. 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')
}

Одним из способов является посещение уникального URL, а затем проверка того, обрабатывается ли ссылка на этот URL как посещенная CSS.

Вы можете увидеть пример этого в "Обнаружение инкогнито" (Мертвая ссылка).

Исследовательская статья того же автора, чтобы заменить ссылку "Обнаружение инкогнито" выше.

В main.html добавить фрейм,

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

и некоторый код 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 = '';
}

Затем в test.html которые загружаются в 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> 

ПРИМЕЧАНИЕ: попытка сделать это из файловой системы может заставить Chrome заплакать о "небезопасном JavaScript". Это, однако, будет работать с веб-сервера.

Вы можете, в JavaScript, увидеть ответ Джурры. За исключением того, что ссылки не выделяются, все в режиме инкогнито не сохраняют историю просмотра и куки. Со страницы справки Google:

  • Веб-страницы, которые вы открываете, и файлы, загруженные во время инкогнито, не записываются в истории просмотров и загрузок.
  • Все новые файлы cookie удаляются после закрытия всех открытых вами окон инкогнито.

Как вы можете видеть, различия между обычным просмотром и инкогнито происходят после посещения веб-страницы, поэтому браузер не взаимодействует с сервером в этом режиме.

Вы можете увидеть, что именно ваш браузер отправляет на сервер, используя один из многих анализаторов HTTP-запросов, например, здесь. Сравните заголовки между обычным сеансом и инкогнито, и вы не увидите никакой разницы.

Если вы разрабатываете расширение, вы можете использовать API вкладок, чтобы определить, является ли окно / вкладка инкогнито.

Более подробную информацию можно найти здесь.

Если вы просто работаете с веб-страницей, это не легко, и она разработана таким образом. Тем не менее, я заметил, что все попытки открыть базу данных (window.database) терпят неудачу, когда в режиме incongnito, это потому, что в режиме инкогнито не разрешается оставлять никаких следов данных на компьютере пользователя.

Я не проверял это, но я подозреваю, что все вызовы localStorage также терпят неудачу.

Для тех, кто ищет решение, вот краткое изложение текущих методов обнаружения режимов частного просмотра в различных браузерах по состоянию на октябрь 2021 года:

  • Chromium: аналогично ответу Винни Джеймса вызовите navigator.storage.estimate (), возьмите свойство quota и сравните его с performance.memory.jsHeapSizeLimit. Если свойство quota меньше jsHeapSizeLimit, это инкогнито. Если jsHeapSizeLimit не определен, используйте 1073741824 (1 ГиБ).

  • Safari для macOS: используйте safari.pushNotification.requestPermission на несуществующем сервере push и найдите ошибку. Если "жест" не отображается в ошибке, значит, это приватный режим.

  • Safari для iOS: создайте iframe и добавьте прослушиватель событий ошибки, используя contentWindow.applicationCache в iframe. Если ошибка срабатывает, это в частном режиме.

  • Firefox: navigator.serviceWorker будет неопределенным в частном окне.

  • Internet Explorer: window.indexedDB будет неопределенным в режиме InPrivate.

Вы можете увидеть реализацию этих методов в скрипте detectIncognito, который есть у меня на GitHub.

При этом используется обещание подождать, пока асинхронный код установит флаг, чтобы впоследствии мы могли использовать его синхронно.

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

тогда мы можем сделать

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

Вот предложенный ответ, написанный в синтаксисе ES6 и немного проясненный.

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)

Другие ответы, похоже, больше не действуют в последних версиях Chrome.

Идея состоит в том, чтобы узнать оценки хранилища, чтобы определить, является ли вкладка инкогнито или нет. Размер хранилища меньше для вкладок в режиме инкогнито.

Запустите этот код как в обычном окне, так и в режиме инкогнито и запишите размер квоты.

      const {quota} = await navigator.storage.estimate();
console.log(quota);

используйте разницу в размере квоты для реализации логики обнаружения режима инкогнито.


ниже логика работает для Chrome v105:

      const { quota } = await navigator.storage.estimate();

if (quota.toString().length === 10) {
  console.log("gotcha: this is incognito tab"); //quota = 1102885027
} else {
  console.log("this is a normal tab"); //quota = 296630877388
}

Кроме того, посмотрите на это решение для гораздо более широкой поддержки (включая другие браузеры )

демо: https://detectincognito.com/

Функция быстрого копирования-вставки на основе ответа Алока (примечание: это асинхронно)

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

использование:

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

Здесь решение с использованием обещаний

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

Как это использовать:

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

Это работает в мае 2021 года: https://jsfiddle.net/2b1dk8oa/

      try{
    var ls = localStorage;
    alert("You are not in Incognito Mode.");
}
catch(e) {  alert("You are in Incognito Mode.");  }

В документации по режиму инкогнито особо сказано, что сайты не будут вести себя иначе. Я считаю, что это означает, что ответ - нет.

Другие вопросы по тегам