Javascript 检测浏览器是否使用私有浏览模式
我正在为一家对安全性有疑心的公司建立一个外联网。他们希望确保(除其他外)他们的用户在其web浏览器中打开私人浏览模式的情况下浏览网站,这样就不会保留cookie或历史记录 我只找到了这个 和 理想的解决方案是不使用或使用最少的javascript。尝试为所有浏览器和平台设置唯一的cookie是否有效?以前有人这样做过吗 谢谢Javascript 检测浏览器是否使用私有浏览模式,javascript,html,security,browser,cookies,Javascript,Html,Security,Browser,Cookies,我正在为一家对安全性有疑心的公司建立一个外联网。他们希望确保(除其他外)他们的用户在其web浏览器中打开私人浏览模式的情况下浏览网站,这样就不会保留cookie或历史记录 我只找到了这个 和 理想的解决方案是不使用或使用最少的javascript。尝试为所有浏览器和平台设置唯一的cookie是否有效?以前有人这样做过吗 谢谢 更新 使用其他海报提到的浏览器指纹的CSS访问技术-谢谢提示 我喜欢它,因为它小巧优雅,但如果可能的话,我仍然希望能够在不使用javascript的情况下使用它 您的网
更新 使用其他海报提到的浏览器指纹的CSS访问技术-谢谢提示
我喜欢它,因为它小巧优雅,但如果可能的话,我仍然希望能够在不使用javascript的情况下使用它 您的网页无法绝对肯定地知道用户处于私人浏览模式。随着安全性实现的更新,检查各种浏览器功能的任何尝试都需要经常更改。它在某些浏览器中可能会工作一段时间,但不是所有浏览器
如果公司如此关注安全性,我建议您使用锁定隐私设置的Firefox或Chromium发行版,只允许自定义客户端连接到外联网。好吧,这样您就无法真正区分私有模式和“阻止所有cookie”,但除了这种罕见的情况,我想它应该会起作用
在我看来,最大的问题是,这是一个非常糟糕的网站设计,并不比90年代常见的好ol“你需要浏览器xxx才能看到这个网站”要好。并不是所有的浏览器都有一个私人浏览模式(就像我鄙视IE一样,比如你删掉了IE7用户),这些用户根本无法访问你的网站 此外,当我在互联网上,我经常有几个标签打开多个网站。这将是真的很烦人,我不得不切换到私人模式只是为了看到该网站,而不能访问其他网站在同一时间 您可以做的一件事是使用会话而不是cookie来设计站点,这样它们就不会被存储(因为您不使用它们…)。至于历史。。。真的,这有什么问题吗?当隐私模式被激活时,网络浏览器 在许多浏览器上,资源的缓存是有限的。可以根据CSS缓存进行检测。有可能发动这次袭击
EFF正在进行一个项目,目的是:。当隐私模式被激活时,浏览器指纹的某些部分将不同。去吧 如果他们没有启用私人浏览功能,你不会阻止他们。 为什么要有一个智能消息框呢 尝试为所有浏览器和平台设置唯一的cookie是否有效?以前有人这样做过吗 我认为最优雅的解决方案是:
- 执行安全泄漏测试
- 如果安全泄漏测试发现问题
- 告诉用户检查设置
- 建议隐私模式
因为正如你所说,并不是每个人都可以或需要启用隐私模式。我通过使用两个HTML页面解决了这个问题。主页面定义状态变量并设置cookie。第二个页面在新窗口(不是选项卡)中打开,读取cookie并将状态设置为cookie值。在MSIE下,当主页处于正常模式时,cookie值将传递给子页。在InPrivate浏览模式下,cookie值不会传递给子页面(但如果打开新选项卡,则会传递该值)
main.html
页面:
<script>
var myCookie="nocookie";
document.cookie="checkInPrivate=1";
var h=window.open("child.html", "_blank", "left=9999,height=200,width=200");
setTimeout(function() {
var status=null;
if (myCookie=="nocookie") {
status="unable to determine if we are InPrivate Browsing mode (child page did not set the cookie)";
} else if (myCookie.indexOf("checkInPrivate")>=0) {
status="not in InPrivate Browsing mode (child page did set the cookie)";
} else {
status="in InPrivate Browsing mode (child page set the cookie value but it was not provided)";
}
alert(status);
}, 200);
</script>
Detecting MSIE's InPrivate Browsing mode...
<script>
window.opener.myCookie=document.cookie;
window.close();
</script>
我使用InPrivate浏览模式是为了防止启用浏览器助手对象(BHO)和浏览器扩展,因为BHO通常是恶意软件,即使使用HTTPS和强身份验证,也可以修改网页。Internet Explorer 9的“隐私”设置中有一个“当InPrivate浏览开始时禁用工具栏和扩展”
但是,这并不是防止恶意浏览器扩展的最终方法:恶意扩展可能会更改主页行为,使其认为未设置并删除mycokie
值。我们会错误地认为我们处于非私有浏览模式
请注意,我的应用程序需要cookies,因此我不使用InPrivate浏览来实现此目的。这里有一个更简单的方法来检测隐私模式。这只适用于Safari。我创建它是因为我正在开发的一个web应用程序使用本地存储。当Safari处于隐私模式时,LocalStorage不可用,因此我的应用程序将无法工作。 在页面加载时,运行下面的脚本。如果我们不能使用localStorage,它会显示一个警报框
try {
// try to use localStorage
localStorage.test = 2;
} catch (e) {
// there was an error so...
alert('You are in Privacy Mode\nPlease deactivate Privacy Mode and then reload the page.');
}
2019年6月更新 谷歌将在Chrome76以后的版本中永久检测私人浏览模式。所以,如果你想检测私人浏览,现在是不可能的(除非你找到一种谷歌没有找到的方法)。检测私人浏览模式的能力已被确认为一个bug,而且从来没有打算这样做 对于遇到这个问题的其他人,请注意,截至2014年,没有可靠或准确的方法来检测是否有人通过Javascript或CSS以匿名/私人/安全浏览模式浏览。以前的解决方案曾经像CSS历史黑客一样工作,但现在所有浏览器供应商都无法使用
在任何情况下,都不应该需要在正常的日常网站上检测私人浏览模式。人们出于自己的原因选择匿名浏览或不匿名浏览 Chrome和Firefox等浏览器不再禁用localStorage等功能。他们只是在一个临时位置命名它,以防止使用它的网站出错。完成浏览后,名称空间将被擦除,而不会保存任何内容。如果您正在测试本地存储支持,而不考虑模式,那么对于支持本地存储的浏览器,它将始终返回true
function retry(isDone, next) {
var current_trial = 0, max_retry = 50, interval = 10, is_timeout = false;
var id = window.setInterval(
function() {
if (isDone()) {
window.clearInterval(id);
next(is_timeout);
}
if (current_trial++ > max_retry) {
window.clearInterval(id);
is_timeout = true;
next(is_timeout);
}
},
10
);
}
function isIE10OrLater(user_agent) {
var ua = user_agent.toLowerCase();
if (ua.indexOf('msie') === 0 && ua.indexOf('trident') === 0) {
return false;
}
var match = /(?:msie|rv:)\s?([\d\.]+)/.exec(ua);
if (match && parseInt(match[1], 10) >= 10) {
return true;
}
return false;
}
function detectPrivateMode(callback) {
var is_private;
if (window.webkitRequestFileSystem) {
window.webkitRequestFileSystem(
window.TEMPORARY, 1,
function() {
is_private = false;
},
function(e) {
console.log(e);
is_private = true;
}
);
} else if (window.indexedDB && /Firefox/.test(window.navigator.userAgent)) {
var db;
try {
db = window.indexedDB.open('test');
} catch(e) {
is_private = true;
}
if (typeof is_private === 'undefined') {
retry(
function isDone() {
return db.readyState === 'done' ? true : false;
},
function next(is_timeout) {
if (!is_timeout) {
is_private = db.result ? false : true;
}
}
);
}
} else if (isIE10OrLater(window.navigator.userAgent)) {
is_private = false;
try {
if (!window.indexedDB) {
is_private = true;
}
} catch (e) {
is_private = true;
}
} else if (window.localStorage && /Safari/.test(window.navigator.userAgent)) {
try {
window.localStorage.setItem('test', 1);
} catch(e) {
is_private = true;
}
if (typeof is_private === 'undefined') {
is_private = false;
window.localStorage.removeItem('test');
}
}
retry(
function isDone() {
return typeof is_private !== 'undefined' ? true : false;
},
function next(is_timeout) {
callback(is_private);
}
);
}
var db = indexedDB.open("test");
db.onerror = function(){/*Firefox PB enabled*/};
db.onsuccess =function(){/*Not enabled*/};
var storage = window.sessionStorage;
try {
storage.setItem("someKeyHere", "test");
storage.removeItem("someKeyHere");
} catch (e) {
if (e.code === DOMException.QUOTA_EXCEEDED_ERR && storage.length === 0) {
//Private here
}
}
if(!window.indexedDB && (window.PointerEvent || window.MSPointerEvent)){
//Privacy Mode
}
var fs = window.RequestFileSystem || window.webkitRequestFileSystem;
if (!fs) {
console.log("FS check failed..");
return;
}
fs(window.TEMPORARY, 100, function (fs) {}, function (err) {
//Incognito mode
});
try {
// Firefox 20+
Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
if (!PrivateBrowsingUtils.isWindowPrivate(window)) {
...
}
} catch(e) {
// pre Firefox 20 (if you do not have access to a doc.
// might use doc.hasAttribute("privatebrowsingmode") then instead)
try {
var inPrivateBrowsing = Components.classes["@mozilla.org/privatebrowsing;1"].
getService(Components.interfaces.nsIPrivateBrowsingService).
privateBrowsingEnabled;
if (!inPrivateBrowsing) {
...
}
} catch(e) {
Components.utils.reportError(e);
return;
}
}
isPrivateWindow(function(is_private) {
if(is_private)
alert('Private');
else
alert('Not Private');
});
function isPrivate(callback) {
callback || (callback = function(){});
var fs = window.RequestFileSystem || window.webkitRequestFileSystem;
if(fs){
return fs(window.TEMPORARY, 1, callback.bind(this, false), callback.bind(this, true));
}
if(window.indexedDB && /Firefox/.test(window.navigator.userAgent)){
try {
var db = window.indexedDB.open('test');
var tryes = 0;
var interval = limit = 10;
var wait = function(check){
if(tryes >= limit){ return callback(true); } // Give up
return window.setTimeout(check, ++tryes * interval);
}
var evaluate = function(){
return db.readyState === 'done' ? callback(!db.result) : wait(evaluate);
}
return wait(evaluate);
} catch (e) {
return callback(true);
}
}
if (!!window.navigator.userAgent.match(/(MSIE|Trident|Edge)/)){
try {
return callback(!window.indexedDB);
} catch (e) {
return callback(true);
}
}
try {
window.openDatabase(null, null, null, null);
return callback(false);
} catch (e) {
return callback(true);
}
}
isPrivate( function(isPrivate) {
console.log('Private mode ===>', isPrivate);
});