Safari Private 模式下 localStorage 的問題


      <p>現如今好多瀏覽器都有「隱身模式」,Safari 管這叫「Private Browing」,國內各種牌子的套殼瀏覽器叫「無痕瀏覽」。私以為從命名上來說,倒是國內更中文一些。</p>

這種模式下瀏覽網頁踏雪無痕,雁過不留聲。具體來說,與正常模式的區別是瀏覽器不會保存歷史記錄,沒有頁面緩存,所有本地數據也都是臨時的,頁面關閉后無法還原。譬如本文下面要講到的 localStorage

並不是說這種模式下絕對安全,服務器仍然對用戶的瀏覽是有感知的。所以 IP 什么的依然可以追蹤。
這世界並不如我們天真設想般爛漫。

--------- LOG ---------
00:01:00 - 一位不具名用戶在零點零一分進行了訪問
00:02:00 - 一位不願透露姓名的用戶在零點零二分打開了你丟棄在服務器 `社會科學/東方藝術鑒賞/東瀛浮世繪` 中的資源 `ae2bx86.jpg`

從功能上來說,普通用戶大概鮮有人知道這一功能(產品情懷就這樣被用戶無視,PM 們默默淚目),而開發者則利用其干凈的特點來開發調試,排除程序之外的因素導致 bug 的可能。

因為所有本地數據都是臨時的,那么問題來了,如果網頁代碼中還使用了諸如 localStorage 的本地存儲,還能生效嗎?

答案是肯定的,但只針對本次訪問。這個肯定只限於桌面瀏覽器。 而手機端則不然。

iOS 上 Safari private 模式下瀏覽器假裝支持 localStorage,並在全局 window 上暴露了該方法。但是當你在調用 localStorage.setItem 進行保存的時候就會報 QUOTA_EXCEEDED_ERR 錯。

QUOTA_EXCEEDED_ERR:DOM Exception 22:An attempt was made to add something to storage...

考察下面的測試代碼:

<button class="setValue">SET</button>
<hr>
<button class="getValue">GET</button>
<script>
    var q = document.querySelector;
    document.querySelector('.setValue').onclick = function () {
        try {
            var time = new Date().getTime();
            localStorage.setItem('time', time);
            alert('set '+time);
        } catch (error) {
            alert(JSON.stringify(error));
        }
    }
    document.querySelector('.getValue').onclick = function () {
        var content = localStorage.getItem('time', new Date().getTime());
        alert('got '+content);
    }
</script>

我在頁面放了兩個按鈕,一個用於向瀏覽器保存值,一個用於獲取。

下面是測試結果:

iOS Safari 隱私模式設置值
iOS Safari 隱私模式設置值

iOS Safari 隱私模式獲取值
iOS Safari 隱私模式獲取值

iOS Chrome 隱私模式設置值
iOS Chrome 隱私模式設置值

iOS Chrome 隱私模式獲取值
iOS Chrome 隱私模式設取值

這表明在 iOS 上,不僅是 Safari 在隱私模式中不能使用 localStorage, Chrome 也不行也不行。這不禁讓人懷疑跟系統平台的策略有關。

博主是谷粉,很早就入手了 Nexus。本着嚴謹的做事態度,那肯定也得拿來測試一下丫。而安卓機上的測試則讓人無法接受。

安卓 Chrome 隱私模式下設置值
安卓 Chrome 隱私模式下設置值

安卓 Chrome 隱私模式下獲取值
安卓 Chrome 隱私模式下獲取值

是的,安卓上面並沒有表現出假裝支持 localStorage,而是真正的支持,能存能取,能取能用!再次證實了上面的懷疑,這種假裝的支持應該是 iOS 的設計哲學。

回過頭來想,隱私模式主要的功能不就是讓用戶的數據不被追蹤嗎,如果能夠存取數據的話,反而沒那么隱私了。從這點來說,localStorage 設置不成功倒也考量了些許人文情懷在里面。

問題想當於回到了開發者手中,我們在開發過程中使用 loaclStorage 就需要對這種情況進行兼容,以避免 js 報錯后影響整個頁面的功能。

下面是兼容代碼示例:

function isLocalStorageSupport(){
    try {
        var isSupport = 'localStorage' in window && window['localStorage'] !== null;
        if (isSupport) {
            localStorage.setItem('__test', '1');
            localStorage.removeItem('__test');
        }
        return isSupport;
    } catch (e) {
        return false;
    }
}

為此,我們可以考慮提取一個輔助類來封裝 localStorage,這樣就可以隨時隨地放心使用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM