2

I need to detect if user is on private mode in Safari both in older versions as well as Safari on IOS 11. Is there a test that would cover both?

Update: Here is a pen that attempts to combine the storage and openDatabase try-catch blocks based on jeprubio's solution below

var isPrivate = false;

// Check private in iOS < 11
var storage = window.sessionStorage;
try {
  console.log('first try for storage')
    storage.setItem("someKeyHere", "test");
    storage.removeItem("someKeyHere");
} catch (e) {
  console.log('first catch')
    if (e.code === DOMException.QUOTA_EXCEEDED_ERR && storage.length === 0) {
        isPrivate = true;
   } 
}

// Check private in iOS 11: https://gist.github.com/cou929/7973956#gistcomment-2272103
try {
  console.log('second try for opendb');
   window.openDatabase(null, null, null, null);
} catch (e) {
  console.log('second catch');
   isPrivate = true;
}

console.log('isPrivate: ' + isPrivate)

alert((isPrivate ? 'You are' : 'You are not')  + ' in private browsing mode');

https://codepen.io/anon/pen/zpMZjp

In Safari new versions (11+) normal browser mode, that does not error on openDatabase test on the console but enters the second catch and isPrivate gets set to true. So, in Safari 11+ non-private mode is also detected as private mode.

Smarajit
  • 143
  • 4
  • 14

2 Answers2

2

Try this:

var isPrivate = false;

// Check private in iOS < 11
var storage = window.sessionStorage;
try {
    storage.setItem("someKeyHere", "test");
    storage.removeItem("someKeyHere");
} catch (e) {
    if (e.code === DOMException.QUOTA_EXCEEDED_ERR && storage.length === 0) {
        isPrivate = true;
   } 
}

// Check private in iOS 11: https://gist.github.com/cou929/7973956#gistcomment-2272103
try {
   window.openDatabase(null, null, null, null);
} catch (_) {
   isPrivate = true;
}

alert((isPrivate ? 'You\'re' : 'You aren\'t')  + ' in private browsing mode');
jeprubio
  • 17,312
  • 5
  • 45
  • 56
  • Seems to be detecting as private mode both for private and non-private modes in latst iOS 11.2.2 Safari. I used that in this pen so it can be tested quickly. https://codepen.io/smarajit_dg/pen/oppRaR – Smarajit Jan 17 '18 at 04:02
  • 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). – Smarajit Jan 19 '18 at 04:19
1

localStorage doesn't work in private browsing on both macOS and iOS.

If you try setItem, it will throw an error. This should allow you to detect private browsing.

You can read more about it here

Valérian
  • 1,068
  • 8
  • 10