文章出處

現如今好多瀏覽器都有「隱身模式」,Safari 管這叫「Private Browing」,國內各種牌子的套殼瀏覽器叫「無痕瀏覽」。私以為從命名上來說,倒是國內更中文一些。
雖然標題暗示要討論的是 Safari,但配圖我喜歡這個 Chrome

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

--------- 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,這樣就可以隨時隨地放心使用。


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()