是否可以通过脚本确定Google Chrome浏览器是否处于隐身模式?
编辑: 我的意思是实际上可以通过用户脚本来实现,但是答案假定JavaScript正在网页上运行。我在这里重新提出了有关用户脚本的问题。
是否可以通过脚本确定Google Chrome浏览器是否处于隐身模式?
编辑: 我的意思是实际上可以通过用户脚本来实现,但是答案假定JavaScript正在网页上运行。我在这里重新提出了有关用户脚本的问题。
Answers:
是。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"));
}
一种方法是访问唯一的URL,然后检查是否已将指向该URL的链接视为被CSS访问过。
您可以在“检测隐身” (无效链接)中看到一个示例。
在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”之声。但是,它将通过Web服务器提供服务。
:visited
:hacks.mozilla.org/2010/03/...
在Chrome 74+中,您可以通过估算可用的文件系统存储空间来确定这一点
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')
}
您可以使用JavaScript查看JHurrah的答案。除了不突出显示链接之外,所有隐身模式都不会保存浏览历史记录和cookie。从Google 帮助页面:
- 隐身时打开的网页和下载的文件不会记录在浏览和下载历史记录中。
- 关闭所有打开的隐身窗口后,所有新的Cookie都会被删除。
如您所见,正常浏览和隐身浏览之间的差异是在您访问网页后发生的,因此,在此模式下,浏览器与服务器之间没有任何通信。
您可以使用许多HTTP请求分析器之一来查看浏览器发送给服务器的确切信息,例如此处的。比较正常会话和隐身会话之间的标题,您将看不到任何区别。
这使用了一个等待异步代码设置标志的承诺,因此我们可以在以后同步使用它。
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');
reject('Check incognito failed')
用resolve(false)
,如果我想isIncognito
成为一个只有真或假的布尔值?谢谢。
Syntax Error: await is a reserved word
,我认为await
总是需要在一个async
函数内。所以我认为这段代码行不通。
reject
如果调用它将引发异常,并且不会返回任何值,所以isIncognito
总是true
或false
编写代码的方式。但是,如果要返回值,也可以在其中使用“解析”。这可能取决于环境如何在全局范围内处理等待?它可以在全局范围内的chrome控制台上运行,但是您可以尝试将所有内容包装起来, (async function() { 'everything here' })();
以便在异步函数中运行
isIncognito
而不是结果,然后在异步函数中运行它:let isIncognito = new Promise( ...etc
然后在其他地方有一个函数,例如(async function() { if( !(await isIncognito) ) {alert('not incognito') } })();
基于Alok的答案的快速复制粘贴功能(注意:这是异步的)
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') });
这是用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)
这里使用诺言的解决方案
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))
隐身模式的文档特别指出,网站的行为不会有所不同。我相信这意味着答案是否定的。
incognito
如果您可以轻松确定它不是很好:)