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

IT技术 javascript google-chrome incognito-mode
2021-02-11 01:35:59

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

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

6个回答

此答案的功能取决于 Chrome 版本。最近的评论是这个作品在v90

是的。FileSystem API 在隐身模式下被禁用。当您处于和未处于隐身模式时,请查看https://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"));
    }

这是最少的hack-ish方式,应该在顶部。干净优雅。
2021-03-22 01:35:59
在 chrome v 77.0.3865.90 中失败
2021-03-25 01:35:59
@user2718671 jsfiddle.net/w49x9f1a在 mac osx 上的最新 Chrome 中对我来说仍然可以正常工作。奇怪的...
2021-03-29 01:35:59
我在 Chrome 上试过。它有效,但逻辑是倒退的。
2021-04-08 01:35:59
由于这些提交很快消失
2021-04-10 01:35:59

在 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')
}
不幸的是,这现在不起作用:例如,在最新的 MS EDGE 中,我在所谓的私有模式下有 224053418 字节。在 Chrome 中,我在隐身模式下看到 234549212 字节。
2021-03-29 01:35:59
这是现在的正确答案。接受的答案应该用这个更新,或者接受的答案应该改变。不要剥夺最初接受的答案,因为它当时是正确的解决方案。
2021-03-30 01:35:59

一种方法是访问一个唯一的 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>

,以及一些 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 公开 :visited 样式信息。CSS 界面会说好像链接具有未访问的颜色。这是至少自 2010 年以来在 WebKit 和 Gecko 浏览器中使用的一项安全措施。这是为了保护用户的历史记录(例如,可以尝试所有可能的 URL,并将访问过的 URL 发送给第三方。这样人们可以获得访问 url 中的令牌等等)。
2021-03-29 01:35:59
不,它没有,iframe“点击”链接。
2021-04-04 01:35:59
这很酷,我没有意识到隐身模式不会突出显示访问过的链接。这需要用户点击一个链接。
2021-04-08 01:35:59
Mozilla 官方文章解释了有关:visited以下内容的隐私更改hacks.mozilla.org/2010/03/...
2021-04-08 01:35:59

您可以在 JavaScript 中查看 JHurrah's answer除了不突出显示链接外,所有隐身模式都不会保存浏览历史记录和 cookie。从谷歌帮助页面

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

正如您访问网页看到的正常浏览和隐身浏览之间的差异一样,因此当浏览器处于这种模式时,浏览器不会与服务器进行任何通信。

您可以使用许多 HTTP 请求分析器之一查看浏览器向服务器发送的确切内容,例如此处的比较普通会话和隐身会话之间的标题,您将看不到任何区别。

最近,它禁用了除用户特别标记为隐身安全的扩展之外的所有扩展。
2021-04-08 01:35:59

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

可以在此处找到更多信息

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

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