您可以通过脚本确定Chrome是否处于隐身模式吗?

Rod*_*own 107 javascript google-chrome incognito-mode

是否可以通过脚本确定Google Chrome是否处于隐身模式?

编辑: 我实际上是指可以通过用户脚本,但答案假设JavaScript正在网页上运行.我在这里重新询问了有关用户脚本的问题.

Alo*_*lok 227

是.在隐身模式下禁用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"));
    }
Run Code Online (Sandbox Code Playgroud)

  • 这是最不受欢迎的方式,应该是最重要的.干净优雅. (19认同)
  • 由于[这些](https://chromium-review.googlesource.com/q/bug:93417)提交,这很快就会消失 (8认同)
  • @user2718671 http://jsfiddle.net/w49x9f1a/ 在 mac osx 上的最新 Chrome 中对我来说仍然可以正常工作。奇怪的... (2认同)
  • chrome v 77.0.3865.90失败 (2认同)

Vin*_*mes 22

在 Chrome 74 到 84.0.4147.135 中,您可以通过估计可用的文件系统存储空间来确定这一点

查看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')
}
Run Code Online (Sandbox Code Playgroud)

  • 现在这是正确的答案。要么应更新已接受的答案,要么应更改已接受的答案。不要放弃最初接受的答案,因为它是当时正确的解决方案。 (6认同)

JHu*_*rah 18

一种方法是访问唯一的URL,然后检查是否将该URL的链接视为CSS访问.

您可以在"检测隐身" (死链接)中看到此示例.

同一作者的研究论文取代上面的Detecting Incognito链接

main.html添加一个iframe,

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

,以及一些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 = '';
}
Run Code Online (Sandbox Code Playgroud)

然后在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> 
Run Code Online (Sandbox Code Playgroud)

注意:从文件系统中尝试此操作可能会让Chrome因"不安全的Javascript"而哭泣.但是,它将通过网络服务器提供服务.

  • 这实际上不起作用,因为大多数浏览器不公开:通过javascript访问样式信息.CSS界面会说链接具有非访问颜色.这是至少自2010年以来一直在WebKit和Gecko浏览器中的安全措施.这是为了保护用户的历史记录(例如,可以尝试所有可能的URL,并将访问过的URL发送给第三方.这样可以获得访问网址中的令牌,什么不是.) (37认同)
  • Mozilla官方文章解释了有关`:visited`的隐私更改:https://hacks.mozilla.org/2010/03/privacy-related-changes-coming-to-css-vistited/ (2认同)

Igo*_*aka 8

您可以在JavaScript中查看JHurrah的答案.除了不突出显示链接外,所有隐身模式都不会保存浏览历史记录和Cookie.来自谷歌帮助页面:

  • 您在隐身时打开的网页和下载的文件不会记录在您的浏览和下载历史记录中.
  • 关闭所有已打开的隐身窗口后,将删除所有新Cookie.

正如您所看到的,您访问网页发生正常浏览和隐身之间的差异,因此当浏览器处于此模式时,浏览器无法与之通信.

您可以使用许多HTTP请求分析器之一来查看浏览器向服务器发送的确切内容,如此处所示.比较正常会话和隐身会话之间的标题,您将看到没有区别.


Kin*_*lan 5

如果您正在开发扩展,那么您可以使用选项卡 API 来确定窗口/选项卡是否隐身。

可以在此处找到更多信息。

如果你只是在处理一个网页,这并不容易,而且它就是这样设计的。但是,我注意到在隐身模式下打开数据库(window.database)的所有尝试都失败了,这是因为在隐身模式下,不允许在用户计算机上留下任何数据痕迹。

我还没有测试过,但我怀疑所有对 localStorage 的调用也失败了。


小智 5

对于那些寻求解决方案的人来说,以下是截至 2021 年 10 月在各种浏览器中检测隐私浏览模式的当前方法的简要概述:

  • Chromium:与 Vinnie James 的答案类似,调用 navigator.storage.estimate(),获取配额属性并将其与 Performance.memory.jsHeapSizeLimit 进行比较。如果配额属性小于 jsHeapSizeLimit,则为隐身。如果 jsHeapSizeLimit 未定义,请使用 1073741824 (1 GiB)。

  • macOS 版 Safari:在不存在的推送服务器上使用 safari.pushNotification.requestPermission 并捕获错误。如果错误中没有出现“手势”,则说明它处于私密模式。

  • iOS 版 Safari:创建一个 iframe 并在 iframe 上使用 contentWindow.applicationCache 添加错误事件侦听器。如果出现错误,则说明它处于私有模式。

  • Firefox:navigator.serviceWorker 在私有窗口中将是未定义的。

  • Internet Explorer:window.indexedDB 在 InPrivate 模式下将是未定义的。

您可以在我在 GitHub 上提供的detectorIncognito脚本中查看这些方法的实现。