简体   繁体   English

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

[英]Can you determine if Chrome is in incognito mode via a script?

Is it possible to determine if Google Chrome is in incognito mode via a script?是否可以通过脚本确定谷歌浏览器是否处于隐身模式?

Edit: I actually meant is it possible via user-script, but the answers assume JavaScript is running on a web page.编辑:我实际上是说是否可以通过用户脚本,但答案假设 JavaScript 在 web 页面上运行。 I've re-asked the question here in regards to user scripts.我在这里重新提出了有关用户脚本的问题。

The functionality of this answer is Chrome version dependant.此答案的功能取决于 Chrome 版本。 The most recent comment was this works in v90最近的评论是这适用于v90

Yes.是的。 The FileSystem API is disabled in incognito mode. FileSystem API 在隐身模式下被禁用。 Check out https://jsfiddle.net/w49x9f1a/ when you are and aren't in incognito mode.当您处于和未处于隐身模式时,请查看https://jsfiddle.net/w49x9f1a/

Sample code:示例代码:

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

In Chrome 74 to 84.0.4147.135 you can determine this by estimating the available file system storage space在 Chrome 74 到 84.0.4147.135 中,您可以通过估计可用的文件系统存储空间来确定这一点

See the jsfiddle查看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')
}

One way is to visit a unique URL and then check to see whether a link to that URL is treated as visited by CSS.一种方法是访问唯一的 URL,然后检查该 URL 的链接是否被 CSS 视为访问过。

You can see an example of this in "Detecting Incognito" (Dead link) .你可以在“Detecting Incognito” (死链接)中看到一个例子。

Research paper by same author to replace Detecting Incognito link above 同一作者的研究论文替换上面的检测隐身链接

In main.html add an iframe,main.html添加一个 iframe,

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

, and some JavaScript code: ,以及一些 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 = '';
}

Then in test.html that are loaded into the iFrame:然后在加载到 iFrame 的test.html中:

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

NOTE: trying this from the filesystem can make Chrome cry about "Unsafe Javascript".注意:从文件系统尝试这个会让 Chrome 抱怨“不安全的 Javascript”。 It will, however, work serving from a webserver.但是,它将从网络服务器提供服务。

You can, in JavaScript, see JHurrah's answer .您可以在 JavaScript 中查看 JHurrah's answer Except for not highlighting links, all incognito mode does is not save browse history and cookies.除了不突出显示链接外,所有隐身模式都不会保存浏览历史和 cookie。 From google help page :从谷歌帮助页面

  • Webpages that you open and files downloaded while you are incognito aren't recorded in your browsing and download histories.您在隐身时打开的网页和下载的文件不会记录在您的浏览和下载历史记录中。
  • All new cookies are deleted after you close all incognito windows that you've opened.关闭所有已打开的隐身窗口后,所有新 cookie 都会被删除。

As you can see the differences between normal browsing and incognito happen after you visit the webpage, hence there is nothing that browser communicates to the server when it's in this mode.正如您访问网页看到的正常浏览和隐身浏览之间的差异一样,因此当浏览器处于这种模式时,浏览器不会与服务器进行任何通信。

You can see what exactly your browser sends to the server using one of many HTTP request analysers, like this one here .您可以使用许多 HTTP 请求分析器之一查看浏览器向服务器发送的确切内容,就像这里的这个 Compare the headers between normal session and incognito and you will see no difference.比较普通会话和隐身会话之间的标题,您将看不到任何区别。

If you are developing an Extension then you can use the tabs API to determine if a window/tab incognito.如果您正在开发扩展,那么您可以使用选项卡 API 来确定窗口/选项卡是否隐身。

More information can be found here .可以在此处找到更多信息。

If you are just working with a webpage, it is not easy, and it is designed to be that way.如果你只是在处理一个网页,这并不容易,而且它就是这样设计的。 However, I have noticed that all attempts to open a database (window.database) fail when in incongnito, this is because when in incognito no trace of data is allowed to be left on the users machine.但是,我注意到在隐身模式下打开数据库(window.database)的所有尝试都失败了,这是因为在隐身模式下,不允许在用户计算机上留下任何数据痕迹。

I haven't tested it but I suspect all calls to localStorage fail too.我还没有测试过,但我怀疑所有对 localStorage 的调用也失败了。

Update This seems to not be working anymore更新这似乎不再起作用了


This uses a promise to wait for the asynchronous code to set a flag, so we can use it synchronously afterward.这使用了一个 promise 来等待异步代码设置一个标志,因此我们可以在之后同步使用它。

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

then we can do那么我们可以做

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

Quick function based on Alok's Answer (note: this is asynchronous)基于Alok's Answer 的快速功能(注意:这是异步的)

Update - not working anymore更新- 不再工作

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

usage:用法:

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

Here is the suggested answer written in ES6 syntaxt and slightly cleand up.这是用 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)

For those looking for a solution, here's a brief rundown of the current methods of detecting Private Browsing modes in various browsers as of October 2021:对于那些寻求解决方案的人,以下是截至 2021 年 10 月在各种浏览器中检测隐私浏览模式的当前方法的简要概述:

  • Chromium: Similar to Vinnie James's answer, call navigator.storage.estimate(), grab the quota property and compare it to performance.memory.jsHeapSizeLimit. Chromium:类似于 Vinnie James 的回答,调用 navigator.storage.estimate(),获取配额属性并将其与 performance.memory.jsHeapSizeLimit 进行比较。 If the quota property is less than jsHeapSizeLimit, it's incognito.如果配额属性小于 jsHeapSizeLimit,则为隐身。 If jsHeapSizeLimit is undefined, use 1073741824 (1 GiB).如果未定义 jsHeapSizeLimit,请使用 1073741824 (1 GiB)。

  • Safari for macOS: Use safari.pushNotification.requestPermission on a non-existent push server & grab the error.适用于 macOS 的 Safari:在不存在的推送服务器上使用 safari.pushNotification.requestPermission 并获取错误。 If "gesture" does not appear in the error, it's in private mode.如果“手势”没有出现在错误中,则它处于私密模式。

  • Safari for iOS: Create an iframe & add an error event listener using contentWindow.applicationCache on the iframe. iOS 版 Safari:创建 iframe 并在 iframe 上使用 contentWindow.applicationCache 添加错误事件侦听器。 If the error trips, it's in private mode.如果错误跳闸,则处于私有模式。

  • Firefox: navigator.serviceWorker will be undefined in a private window. Firefox:navigator.serviceWorker 将在私人窗口中未定义。

  • Internet Explorer: window.indexedDB will be undefined in InPrivate mode. Internet Explorer:在 InPrivate 模式下,window.indexedDB 将是未定义的。

You can see an implementation of these methods in the detectIncognito script I have available on GitHub.您可以在我在 GitHub 上提供的detectIncognito脚本中查看这些方法的实现。

Other answers seem to be no longer valid in recent chrome versions.其他答案在最近的 chrome 版本中似乎不再有效。

The idea is to find out storage estimates to determine if the tab is incognito or not.这个想法是找出存储估计以确定选项卡是否隐身。 Storage size is less for incognito tabs.隐身标签的存储空间较小。

Run this code in both normal and incognito window and note down the quota size.在正常和隐身模式下运行此代码 window 并记下配额大小。

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

use quota size difference to implement the logic for incognito mode detection.使用配额大小差异来实现隐身模式检测的逻辑。


below logic works for Chrome v105 :以下逻辑适用于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
}

Also, look at this solution for much wider support (includes other browsers as well) detectIncognito.ts此外,查看此解决方案以获得更广泛的支持(也包括其他浏览器) detectIncognito.ts

demo: https://detectincognito.com/演示: https://detetincognito.com/

Is it possible to determine if Google Chrome is in incognito mode via a script?是否可以通过脚本确定Google Chrome浏览器是否处于隐身模式?

Edit: I actually meant is it possible via user-script, but the answers assume JavaScript is running on a web page.编辑:我的意思是实际上可以通过用户脚本来实现,但是答案假定JavaScript正在网页上运行。 I've re-asked the question here in regards to user scripts.我在这里重新提出了有关用户脚本的问题。

This works in May 2021: https://jsfiddle.net/2b1dk8oa/这在 2021 年 5 月有效: https : //jsfiddle.net/2b1dk8oa/

The script has to be executed in a webpage, which is in an iframe.该脚本必须在网页中执行,该网页位于 iframe 中。

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

Is it possible to determine if Google Chrome is in incognito mode via a script?是否可以通过脚本确定Google Chrome浏览器是否处于隐身模式?

Edit: I actually meant is it possible via user-script, but the answers assume JavaScript is running on a web page.编辑:我的意思是实际上可以通过用户脚本来实现,但是答案假定JavaScript正在网页上运行。 I've re-asked the question here in regards to user scripts.我在这里重新提出了有关用户脚本的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM