Safari のプライベートモードは Web Storage が動作しない

2015年1月8日 22:38

私事ながらというか、Mac ユーザでありながら Safari の事情にいまいち疎いのは、普段はもっぱら Google Chrome を使っているためである。なので、ツイート中で「プライベートブラウジング」とか「プライベートモード」などと知った風に書いてはいるが、この不具合に遭遇した当初は正式になんと呼べばいいかも分かりかねていた。おそらく Chrome で言うところの「シークレットモード」みたいなものなんだろうな、ぐらいのレベル。

調べてみると「シークレットモード」なんて意味深な呼び名を採用しているのは Chrome だけで、Safari はもちろん Firefox も Opera も、さらには IE でさえも「プライベートブラウジング」としている。なのでこれが一般的な呼称なのだろう。

プライベートブラウジングを選ぶとブラウザは「プライベートモード」へ移行する。いわゆる「履歴を残さないモード」だ。が、各ブラウザごとにこのモードの挙動が異なり、さらに、今回取り上げている Session Storage をはじめとする HTML5 のストレージ技術(Web Storage)の振る舞いがまたややこしかったりするのだ。詳しくは こちらのページ あたりを参照していただくとして、ここでは Safari の不思議な挙動についてのみフォローしておく。

Session Storage(および Local Storage)は Safari のプライベートモードで(なぜか)エラーになる。プライベートブラウジングの目的は履歴を残さないことなので、ブラウザを閉じた時点でストレージの内容が削除されるのが本来の挙動だと思うし、他のブラウザは実際にそのように動作するようだ。果たしてこれは Safari の不具合なのか、そして今後のバージョンアップで改善される予定があるのか、今のところは不明である。

古いブラウザなど Web Storage が使えない場合を考慮し、以下のような対応チェックを行なうケースは多いと思う。

if (window.localStorage) {
    window.localStorage.setItem(_key, _value);
}

しかしながら、Safari のプライベートモードに限っては window.localStoragefalse を返さず、実際に setItem() を実行した時点で QUOTA_EXCEEDED_ERR エラーとなる。なので、対応策としては try-catch による回避ぐらいしかないと思われる。

try {
    window.localStorage.setItem(_key, _value);
} catch(e) {
    // 何もしない
}

ユーザに Safari のプライベートモードが原因だということを知らせたいなら、QUOTA_EXCEEDED_ERR のエラーコードが 22 だということを利用して以下のような処理も有効だろう。

try {
    window.localStorage.setItem(_key, _value);
} catch(e) {
    if (e.code == 22) {
        alert('Safariブラウザのプライベートモードで...云々');
    }
}

なんだか釈然としないが、今のところこの方法しかなさそうだ。