-
-
Save cou929/7973956 to your computer and use it in GitHub Desktop.
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); | |
} | |
); | |
} |
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
</head> | |
<body> | |
<div id="result"></div> | |
<script src="detect-private-browsing.js"></script> | |
<script> | |
detectPrivateMode( | |
function(is_private) { | |
document.getElementById('result').innerHTML = typeof is_private === 'undefined' ? 'cannot detect' : is_private ? 'private' : 'not private'; | |
} | |
); | |
</script> | |
</body> | |
</html> |
IE and Mozilla is returning private, but its not.
@JessicaYeh on desktop version 11 not works more too.
On Firefox ESR 53.0 not working. The script always returns as private.
I asked a question on Stackoverflow with more details about Firefox specific errors, here.
@Maykonn Seems like navigator.doNotTrack
is not null
in Safari private mode on iOS
Seems to be giving a false "Not private" - Meaning it should say private but it isn't - Using GeckFX (FireFox) .NET Control, I have the appropriate configurations for private mode, I just don't think its compatible with FF- Information on what I am using: https://bitbucket.org/geckofx/geckofx-45.0/issues/94/private-browsing
Not sure if its a JS issue or its something with the control/engine itself. My guess is it has something to do with the JS, with how it is detecting it via the code - or the version fo the engine itself although that should be ok.
I'm testing in various FF versions and from version 52 below don't working. Always returning as private browsing.
Safari latest version don't working too. I'm making tests with navigator.doNotTrack
@forberg, thanks.
navigator.doNotTrack is just a Safari feature that asks sites not to track the user, it can be opted into by going to safari->preferences->privacy. navigator.doNotTrack is not null if the user has checked that option, it is not indicative of whether the user is in private mode or not.
I'm still investigating how to detect private browsing in Safari, if anyone else is interested in this feature we should join forces
Note: this does not seem to detect private browsing for iOS 11 Safari. It detects find in iOS 10 and 9 Safari.
Guys I found a solution.
You can detect private browsing in iOS 11 using below code. 😄
No matter user's DNT option is checked or not, you can detect private browsing mode properly.
var isPrivate = false;
try {
window.openDatabase(null, null, null, null);
} catch (_) {
isPrivate = true;
}
alert((isPrivate ? 'You\'re' : 'You aren\'t') + ' in private browsing mode');
It worked for me perfectly. If it doesn't, please let me know.
@ckimy Think you very much! Let's dance!
@ckimy This code does not work in ios10 above
Hey, guys! There is my own version of snippet, based on original gist and some comments.
Check this out: https://jsfiddle.net/n0hnu5te/1/
It works for me in:
- IE11
- Chrome 63.0
- Mobile Chrome 62.0 (Android)
Let's test it on different devices/oses/browsers!
@yimaneilicj Of course, this snippet is only for ios11. You can combine this snippet with another library/modules for other browsers. @dkuryakin had done this job for us! :)
Does anyone have a snippet that detects private mode on Safari on iOS11 as well as older Safari?
Update: Here is a pen that attempts to combine the storage and openDatabase try-catch blocks.
https://codepen.io/anon/pen/zpMZjp
The test window.openDatabase(null, null, null, null)
is not expected to throw an exception in Safari non-private browser mode, but it does (exception code 18).
In Safari new versions (11+ or iOS11+ Safari) normal browser mode, the second test (for openDatabase) enters the catch and isPrivate gets set to true. So, in Safari 11+ non-private mode is also detected as private mode. Anyone with a working solution on a server? It seems to work as expected in localhost, but window.openDatabase(null, null, null, null)
throws exception both in normal and private mode when hosted in some server, as can be seen in the pen.
IE can return true when it's not when you have your restriction on your policy to disable indexedDB
I've noticed in Safari 11 normal browsing mode window.openDatabase(null, null, null, null)
will throw an exception if a user has just cleared their history and refreshed.
I'm using Safari 11.1 (11605.1.33.1.4) on OSX 10.11.6 and am getting "not private" when using a private window.
I switched line 82 to "true" and that seemed to fix it for me.
- Incognito mode detection
- Detection of bot browsing
- You can ignore mode(normal or incognito) detection if is a bot browsing
- Configure custom callbacks when private or not (you can implement a paywall in a callback when incognito detected)
https://github.com/Maykonn/js-detect-incognito-private-browsing-paywall
Has anyone found a solution for chrome IOS 12 + for detecting private mode?
@tormod17 where/how are you trying to attempting this check? Any chance you're doing this in an iframe?
False positive on iOS 12+ as tormod17 mentioned, are we playing whack a mole here with each iOS release/patch?
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);
});
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); });
window chrome the result is error!
This does not seem to work anymore
https://twitter.com/paul_irish/status/1138471166115368960
for desktop you can use
https://mishravikas.com/articles/2019-07/bypassing-anti-incognito-detection-google-chrome.html
(async () => {
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");
}
})();
Incorrect reading for Chrome 81 when not in incognito
It's able to detect private mode in chrome 85
not working with latest version
On iOS 11 Safari (and probably the new version of desktop Safari too? but didn't check that one), that trick of seeing if
window.localStorage.setItem('test', 1);
throws an error no longer works, because it no longer throws an error, and it also properly sets the localStorage item. Has anyone figured out any other way to check for private browsing mode in the new versions of Safari?