html5 localStorage error dengan Safari: "QUOTA_EXCEEDED_ERR: DOM Exception 22: Upaya telah dilakukan untuk menambahkan sesuatu ke penyimpanan yang melebihi kuota."

133

Webapp saya memiliki kesalahan javascript di ios safari private browsing:

JavaScript: kesalahan

tidak terdefinisi

QUOTA_EXCEEDED_ERR: DOM Pengecualian 22: Upaya telah dilakukan untuk menambahkan sesuatu ke penyimpanan ...

kode saya:

localStorage.setItem('test',1)
Leiyonglin
sumber
Gunakan fitur deteksi yang menguji untuk masalah khusus ini . Jika penyimpanan tidak tersedia, mempertimbangkan shimming localStorage dengan memoryStorage . disclaimer: Saya penulis paket terkait
Stijn de Witt
4
Hai teman-teman, saya bantu menjaga safaridriver. Masalah ini adalah bug lama di WebKit yang baru-baru ini diperbaiki. Penyimpanan lokal dan penyimpanan sesi sekarang berfungsi di Safari 10.1 dan yang lebih baru. Perbaikan ini memengaruhi mode Penjelajahan Pribadi dan mode Otomatisasi normal (digunakan oleh WebDriver).
Brian Burg

Jawaban:

183

Rupanya ini dengan desain. Ketika Safari (OS X atau iOS) dalam mode penjelajahan pribadi, tampaknya seolah-olah localStoragetersedia, tetapi mencoba untuk memanggil setItemmelempar pengecualian.

store.js line 73
"QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage that exceeded the quota."

Apa yang terjadi adalah bahwa objek jendela masih terbuka localStoragedi namespace global, tetapi ketika Anda menelepon setItem, pengecualian ini dilemparkan. Panggilan apa pun untuk removeItemdiabaikan.

Saya percaya perbaikan yang paling sederhana (meskipun saya belum menguji browser lintas ini) akan mengubah fungsi isLocalStorageNameSupported()untuk menguji bahwa Anda juga dapat menetapkan beberapa nilai.

https://github.com/marcuswestin/store.js/issues/42

function isLocalStorageNameSupported() 
{
    var testKey = 'test', storage = window.sessionStorage;
    try 
    {
        storage.setItem(testKey, '1');
        storage.removeItem(testKey);
        return localStorageName in win && win[localStorageName];
    } 
    catch (error) 
    {
        return false;
    }
}
KingKongFrog
sumber
1
Ini tidak harus disebabkan oleh mode penyamaran ... meskipun saya kira OP tidak ingin menyimpan beberapa megabita data;)
Christoph
5
Lihatlah intisari ini yang menunjukkan riwayat singkat mendeteksi penyimpanan lokal oleh Paul Irish.
Mottie
4
Jadi dalam hal localStorage tidak akan berfungsi di Safari, apakah menyimpan segala sesuatu di cookie adalah pilihan terbaik berikutnya?
Will Hitchcock
5
Mirip dengan contoh Paul Irish, saya sarankan berubah return localStorageName in win && win[localStorageName];menjadi return true. Maka Anda memiliki fungsi yang mengembalikan benar atau salah dengan aman tergantung pada ketersediaan Penyimpanan lokal. Misalnya:if (isLocalStorageNameSupported()) { /* You can use localStorage.setItem */ } else { /* you can't use localStorage.setItem */ }
DrewT
1
Diverifikasi bahwa masalahnya bukan hanya dengan jendela pribadi tetapi juga jendela safari normal.
codemirror
38

Perbaikan yang diposting pada tautan di atas tidak berhasil untuk saya. Ini berhasil:

function isLocalStorageNameSupported() {
  var testKey = 'test', storage = window.localStorage;
  try {
    storage.setItem(testKey, '1');
    storage.removeItem(testKey);
    return true;
  } catch (error) {
    return false;
  }
}

Berasal dari http://m.cg/post/13095478393/detect-private-browsing-mode-in-mobile-safari-on-ios5

cyberwombat
sumber
20
Ada alasan tertentu mengapa Anda (dan @KingKongFrog) menggunakan window.sessionStorage untuk mendeteksi apakah Anda dapat menulis ke localStorage atau apakah kami dalam siklus salah ketik yang aneh salin-tempel?
Yetti
@ Yetti jika Anda melihat kesalahan ketik, mengapa Anda tidak memperbaikinya baik dalam edit atau dalam komentar Anda? Sejauh yang saya sadari window.sessionStoragebenar. Ini pasti berfungsi dalam kode saya. Harap tunjukkan perbaikan yang sebenarnya Anda ketahui.
Novocaine
7
@Novocaine Komentar saya menunjukkan bahwa mereka menggunakan sessionStorage dalam fungsi yang ada untuk memeriksa dukungan localStorage. Ya, sepertinya masih berfungsi, tetapi, seperti yang ditulis, nama fungsi menyesatkan untuk apa yang sebenarnya sedang diuji. Saya memilih untuk berkomentar, daripada mengedit, karena saya pikir saya kehilangan sesuatu dan berharap untuk belajar dari orang-orang ini. Sayangnya, mereka belum menjawab atau melakukan koreksi, jadi inilah kami.
Yetti
3
@ Yetti Terima kasih telah menjelaskan. Saya mengerti apa yang sedang Anda bicarakan sekarang. ; -]
Novocaine
2
@ DawsonToth tidak itu karena saya memanggil fungsi isLocalStorageNameSupporteddan sedang memeriksa window.sessionStorage. Hasil akhirnya sama tapi agak membingungkan. Jawabannya diedit untuk memperjelas.
cyberwombat
25

Seperti disebutkan dalam jawaban lain, Anda akan selalu mendapatkan QuotaExceededError di Safari Private Browser Mode di iOS dan OS X saat localStorage.setItem(atausessionStorage.setItem ) dipanggil.

Salah satu solusinya adalah melakukan pemeriksaan coba / tangkap atau Modernizr di setiap contoh penggunaansetItem .

Namun jika Anda ingin shim yang secara global menghentikan kesalahan ini, untuk mencegah sisa JavaScript Anda rusak, Anda dapat menggunakan ini:

https://gist.github.com/philfreo/68ea3cd980d72383c951

// Safari, in Private Browsing Mode, looks like it supports localStorage but all calls to setItem
// throw QuotaExceededError. We're going to detect this and just silently drop any calls to setItem
// to avoid the entire page breaking, without having to do a check at each usage of Storage.
if (typeof localStorage === 'object') {
    try {
        localStorage.setItem('localStorage', 1);
        localStorage.removeItem('localStorage');
    } catch (e) {
        Storage.prototype._setItem = Storage.prototype.setItem;
        Storage.prototype.setItem = function() {};
        alert('Your web browser does not support storing settings locally. In Safari, the most common cause of this is using "Private Browsing Mode". Some settings may not save or some features may not work properly for you.');
    }
}
philfreo
sumber
11

Dalam konteks saya, baru saja mengembangkan abstraksi kelas. Ketika aplikasi saya diluncurkan, saya memeriksa apakah localStorage berfungsi dengan memanggil getStorage () . Fungsi ini juga mengembalikan:

  • baik penyimpanan lokal jika penyimpanan lokal bekerja
  • atau implementasi LocalStorageAlternative kelas kustom

Dalam kode saya, saya tidak pernah memanggil localStorage secara langsung. Saya memanggil cusSto global var, saya telah menginisialisasi dengan memanggil getStorage () .

Dengan cara ini, ini berfungsi dengan penelusuran pribadi atau versi Safari tertentu

function getStorage() {

    var storageImpl;

     try { 
        localStorage.setItem("storage", ""); 
        localStorage.removeItem("storage");
        storageImpl = localStorage;
     }
     catch (err) { 
         storageImpl = new LocalStorageAlternative();
     }

    return storageImpl;

}

function LocalStorageAlternative() {

    var structureLocalStorage = {};

    this.setItem = function (key, value) {
        structureLocalStorage[key] = value;
    }

    this.getItem = function (key) {
        if(typeof structureLocalStorage[key] != 'undefined' ) {
            return structureLocalStorage[key];
        }
        else {
            return null;
        }
    }

    this.removeItem = function (key) {
        structureLocalStorage[key] = undefined;
    }
}

cusSto = getStorage();
Pierre Le Roux
sumber
2
Terima kasih Pierre, jawaban Anda menginspirasi saya. Saya akhirnya mengemas semuanya dalam modul bagus bernama memorystorage . Open Source tentu saja. Untuk orang lain yang memiliki masalah yang sama, lihat ini mungkin membantu Anda.
Stijn de Witt
Ha. Saya melakukan hal yang sama (mandiri). Tetap menggunakan variabel localStorage (di Safari, setidaknya, Anda tidak bisa menimpa variabel localStorage (ini 'read-only'), tetapi Anda dapat menetapkan kembali setItem / removeItem / getItem).
Ruben Martinez Jr.
@StijndeWitt, bagaimana saya bisa mengakses nilai penyimpanan saya di halaman lain? Sebagai contoh, saya memilikinya di helper.php var store = MemoryStorage ('my-app'); store.setItem ('myString', 'Hello MemoryStorage!'); Saya ingin mengakses nilai myString di lecture.php. Saya mencoba memulai penyimpanan memori di halaman tetapi masih menunjukkan objek kosong.
user1149244
@ user1149244 Memorystorage bersifat lokal ke halaman. Ini mensimulasikan Web Storage API dan karenanya dapat digunakan sebagai mundur ketika localStorage dan sessionStorage tidak tersedia. Namun data hanya akan disimpan dalam memori halaman (karenanya namanya). Jika Anda membutuhkan data untuk disimpan di seluruh halaman, cookie dapat membantu Anda. Tetapi sangat terbatas dalam jumlah data yang dapat disimpan. Selain itu tidak banyak yang bisa dilakukan.
Stijn de Witt
2
@ user1149244 Bukankah ini seharusnya menyimpan nilai di browser? Tidak, tidak bisa. Ada 3 cara untuk menyimpan hal-hal sisi klien dari satu refresh halaman ke yang lain: cookie, sessionStorage / localStorage dan IndexedDB. Dua yang terakhir relatif baru. sessionStorage dan localStorage didukung secara luas sehingga Anda dapat menggunakannya pada dasarnya di mana saja. kecuali dalam mode penjelajahan pribadi , yang menjadi masalah masalah ini. Program rusak karena penyimpanan tidak ada. memorystorage hanya menyediakan fallback yang selalu berfungsi saat berada di halaman, tetapi sebenarnya tidak bisa menyimpan data. Itu sebuah rintisan. Tapi tidak ada kesalahan.
Stijn de Witt
5

Tampaknya Safari 11 mengubah perilaku, dan sekarang penyimpanan lokal berfungsi di jendela browser pribadi. Hore!

Aplikasi web kami yang dulu gagal dalam penjelajahan pribadi Safari sekarang berfungsi dengan sempurna. Itu selalu berfungsi dengan baik dalam mode penjelajahan pribadi Chrome, yang selalu memungkinkan penulisan ke penyimpanan lokal.

Ini didokumentasikan dalam catatan rilis Pratinjau Teknologi Safari Apple - dan catatan rilis WebKit - untuk rilis 29, yang pada bulan Mei 2017.

Secara khusus:

  • Memperbaiki QuotaExceededError saat menyimpan ke localStorage dalam mode penelusuran pribadi atau sesi WebDriver - r215315
karlbecker_com
sumber
4

Untuk memperluas jawaban orang lain, berikut adalah solusi ringkas yang tidak memaparkan / menambah variabel baru. Itu tidak mencakup semua pangkalan, tetapi harus sesuai dengan kebanyakan orang yang hanya ingin aplikasi satu halaman tetap berfungsi (meskipun tidak ada data yang persisten setelah memuat ulang).

(function(){
    try {
        localStorage.setItem('_storage_test', 'test');
        localStorage.removeItem('_storage_test');
    } catch (exc){
        var tmp_storage = {};
        var p = '__unique__';  // Prefix all keys to avoid matching built-ins
        Storage.prototype.setItem = function(k, v){
            tmp_storage[p + k] = v;
        };
        Storage.prototype.getItem = function(k){
            return tmp_storage[p + k] === undefined ? null : tmp_storage[p + k];
        };
        Storage.prototype.removeItem = function(k){
            delete tmp_storage[p + k];
        };
        Storage.prototype.clear = function(){
            tmp_storage = {};
        };
    }
})();
Jon
sumber
3

Saya memiliki masalah yang sama menggunakan kerangka kerja ionik (Angular + Cordova). Saya tahu ini tidak menyelesaikan masalah, tetapi ini adalah kode untuk Aplikasi Angular berdasarkan jawaban di atas. Anda akan memiliki solusi singkat untuk penyimpanan lokal pada Safari versi iOS.

Ini kodenya:

angular.module('myApp.factories', [])
.factory('$fakeStorage', [
    function(){
        function FakeStorage() {};
        FakeStorage.prototype.setItem = function (key, value) {
            this[key] = value;
        };
        FakeStorage.prototype.getItem = function (key) {
            return typeof this[key] == 'undefined' ? null : this[key];
        }
        FakeStorage.prototype.removeItem = function (key) {
            this[key] = undefined;
        };
        FakeStorage.prototype.clear = function(){
            for (var key in this) {
                if( this.hasOwnProperty(key) )
                {
                    this.removeItem(key);
                }
            }
        };
        FakeStorage.prototype.key = function(index){
            return Object.keys(this)[index];
        };
        return new FakeStorage();
    }
])
.factory('$localstorage', [
    '$window', '$fakeStorage',
    function($window, $fakeStorage) {
        function isStorageSupported(storageName) 
        {
            var testKey = 'test',
                storage = $window[storageName];
            try
            {
                storage.setItem(testKey, '1');
                storage.removeItem(testKey);
                return true;
            } 
            catch (error) 
            {
                return false;
            }
        }
        var storage = isStorageSupported('localStorage') ? $window.localStorage : $fakeStorage;
        return {
            set: function(key, value) {
                storage.setItem(key, value);
            },
            get: function(key, defaultValue) {
                return storage.getItem(key) || defaultValue;
            },
            setObject: function(key, value) {
                storage.setItem(key, JSON.stringify(value));
            },
            getObject: function(key) {
                return JSON.parse(storage.getItem(key) || '{}');
            },
            remove: function(key){
                storage.removeItem(key);
            },
            clear: function() {
                storage.clear();
            },
            key: function(index){
                storage.key(index);
            }
        }
    }
]);

Sumber: https://gist.github.com/jorgecasar/61fda6590dc2bb17e871

Nikmati pengkodean Anda!

jorgecasar
sumber
1
Meskipun ini tidak menjawab pertanyaan, ini adalah hal pertama yang muncul ketika saya mencari masalah di Google. Langkah selanjutnya adalah mencari solusi untuk Angular tetapi berkat komentar ini saya tidak harus pergi ke tempat lain. Jadi, mungkin tidak langsung menjawab pertanyaan tetapi sudah bagus untuk saya dan kemungkinan untuk orang lain!
Leonard
2

Inilah solusi untuk AngularJS menggunakan IIFE dan meningkatkan fakta bahwa layanan adalah lajang .

Hal ini menghasilkan isLocalStorageAvailablepengaturan yang segera ketika layanan pertama kali disuntikkan dan menghindari menjalankan cek yang tidak perlu setiap kali penyimpanan lokal perlu diakses.

angular.module('app.auth.services', []).service('Session', ['$log', '$window',
  function Session($log, $window) {
    var isLocalStorageAvailable = (function() {
      try {
        $window.localStorage.world = 'hello';
        delete $window.localStorage.world;
        return true;
      } catch (ex) {
        return false;
      }
    })();

    this.store = function(key, value) {
      if (isLocalStorageAvailable) {
        $window.localStorage[key] = value;
      } else {
        $log.warn('Local Storage is not available');
      }
    };
  }
]);
Dermaga-Luc Gendreau
sumber
1

Saya baru saja membuat repo ini untuk menyediakan sessionStoragedan localStoragefitur untuk browser yang tidak didukung atau dinonaktifkan.

Browser yang didukung

  • IE5 +
  • Chrome semua versi
  • Mozilla semua versi
  • Yandex semua versi

Bagaimana itu bekerja

Ini mendeteksi fitur dengan tipe penyimpanan.

function(type) {
    var testKey = '__isSupported',
        storage = window[type];
    try {
        storage.setItem(testKey, '1');
        storage.removeItem(testKey);
        return true;
    } catch (error) {
        return false;
    }
};

Setel StorageService.localStorageke window.localStoragejika didukung atau membuat penyimpanan cookie. Setel StorageService.sessionStorageke window.sessionStoragejika didukung atau membuat penyimpanan dalam memori untuk SPA, penyimpanan cookie dengan fitur sesion untuk non SPA.

Ahmet Can Güven
sumber
1
Terima kasih, perpustakaan Anda banyak membantu!
Mathieu
1

Berikut ini adalah versi layanan Angular2 + untuk alternatif penyimpanan memori, Anda bisa menyuntikkan ke komponen Anda, berdasarkan jawaban Pierre Le Roux.

import { Injectable } from '@angular/core';

// Alternative to localstorage, memory
// storage for certain browsers in private mode
export class LocalStorageAlternative {
    private  structureLocalStorage = {};

    setItem(key: string, value: string): void {
        this.structureLocalStorage[key] = value;
    }

    getItem(key: string): string {
        if (typeof this.structureLocalStorage[key] !== 'undefined' ) {
            return this.structureLocalStorage[key];
        }
        return null;
    }

    removeItem(key: string): void {
        this.structureLocalStorage[key] = undefined;
    }
}

@Injectable()
export class StorageService {
    private storageEngine;

    constructor() {
        try {
            localStorage.setItem('storage_test', '');
            localStorage.removeItem('storage_test');
            this.storageEngine = localStorage;
        } catch (err) {
            this.storageEngine = new LocalStorageAlternative();
        }
    }

    setItem(key: string, value: string): void {
        this.storageEngine.setItem(key, value);
    }

    getItem(key: string): string {
        return this.storageEngine.getItem(key);
    }

    removeItem(key: string): void {
        this.storageEngine.removeItem(key);
    }

}
Gabriel Alack
sumber
0

Jangan menggunakannya jika tidak didukung dan untuk memeriksa dukungan panggil saja fungsi ini

berbagi dalam Es6, baca dan tulis contoh LocalStorage lengkap dengan cek dukungan

const LOCAL_STORAGE_KEY = 'tds_app_localdata';

const isSupported = () => {
  try {
    localStorage.setItem('supported', '1');
    localStorage.removeItem('supported');
    return true;
  } catch (error) {
    return false;
  }
};


const writeToLocalStorage =
  components =>
    (isSupported ?
      localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(components))
      : components);

const isEmpty = component => (!component || Object.keys(component).length === 0);

const readFromLocalStorage =
  () => (isSupported ? JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY)) || {} : null);

Ini akan memastikan kunci Anda diatur dan diambil dengan benar di semua browser.

Tarandeep Singh
sumber
0

Saya telah membuat tambalan untuk masalah ini. Cukup saya memeriksa apakah browser memang mendukung localStorage atau sessionStorage atau tidak. Jika tidak maka mesin penyimpanan akan menjadi Cookie. Tetapi sisi negatifnya adalah Cookie memiliki memori penyimpanan yang sangat kecil :(

function StorageEngine(engine) {
    this.engine = engine || 'localStorage';

    if(!this.checkStorageApi(this.engine)) {
        // Default engine would be alway cooke
        // Safari private browsing issue with localStorage / sessionStorage
        this.engine = 'cookie';
    }
}

StorageEngine.prototype.checkStorageApi = function(name) {
    if(!window[name]) return false;
    try {
        var tempKey = '__temp_'+Date.now();
        window[name].setItem(tempKey, 'hi')
        window[name].removeItem(tempKey);
        return true;
    } catch(e) {
        return false;
    }
}

StorageEngine.prototype.getItem = function(key) {
    if(['sessionStorage', 'localStorage'].includes(this.engine)) {
        return window[this.engine].getItem(key);
    } else if('cookie') {
        var name = key+"=";
        var allCookie = decodeURIComponent(document.cookie).split(';');
        var cval = [];
        for(var i=0; i < allCookie.length; i++) {
            if (allCookie[i].trim().indexOf(name) == 0) {
                cval = allCookie[i].trim().split("=");
            }   
        }
        return (cval.length > 0) ? cval[1] : null;
    }
    return null;
}

StorageEngine.prototype.setItem = function(key, val, exdays) {
    if(['sessionStorage', 'localStorage'].includes(this.engine)) {
        window[this.engine].setItem(key, val);
    } else if('cookie') {
        var d = new Date();
        var exdays = exdays || 1;
        d.setTime(d.getTime() + (exdays*24*36E5));
        var expires = "expires="+ d.toUTCString();
        document.cookie = key + "=" + val + ";" + expires + ";path=/";
    }
    return true;
}


// ------------------------
var StorageEngine = new StorageEngine(); // new StorageEngine('localStorage');
// If your current browser (IOS safary or any) does not support localStorage/sessionStorage, then the default engine will be "cookie"

StorageEngine.setItem('keyName', 'val')

var expireDay = 1; // for cookie only
StorageEngine.setItem('keyName', 'val', expireDay)
StorageEngine.getItem('keyName')
Saddam H
sumber
0

Jawaban yang diterima tampaknya tidak memadai dalam beberapa situasi.

Untuk memeriksa apakah localStorageatau sessionStoragedidukung, saya menggunakan cuplikan berikut dari MDN .

function storageAvailable(type) {
    var storage;
    try {
        storage = window[type];
        var x = '__storage_test__';
        storage.setItem(x, x);
        storage.removeItem(x);
        return true;
    }
    catch(e) {
        return e instanceof DOMException && (
            // everything except Firefox
            e.code === 22 ||
            // Firefox
            e.code === 1014 ||
            // test name field too, because code might not be present
            // everything except Firefox
            e.name === 'QuotaExceededError' ||
            // Firefox
            e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
            // acknowledge QuotaExceededError only if there's something already stored
            (storage && storage.length !== 0);
    }
}

Gunakan cuplikan ini seperti ini, dan mundur ke, misalnya, menggunakan cookie:

if (storageAvailable('localStorage')) {
  // Yippee! We can use localStorage awesomeness
}
else {
  // Too bad, no localStorage for us
  document.cookie = key + "=" + encodeURIComponent(value) + expires + "; path=/";
}

Saya telah membuat paket fallbackstorage yang menggunakan snippet ini untuk memeriksa ketersediaan penyimpanan dan fallback ke MemoryStorage yang diimplementasikan secara manual.

import {getSafeStorage} from 'fallbackstorage'

getSafeStorage().setItem('test', '1') // always work
transang
sumber
-1
var mod = 'test';
      try {
        sessionStorage.setItem(mod, mod);
        sessionStorage.removeItem(mod);
        return true;
      } catch (e) {
        return false;
      }
Naim DOGAN
sumber
1
Mungkin Anda ingin menambahkan beberapa kata penjelasan?
Bogl
-2

Skrip berikut memecahkan masalah saya:

// Fake localStorage implementation. 
// Mimics localStorage, including events. 
// It will work just like localStorage, except for the persistant storage part. 

var fakeLocalStorage = function() {
  var fakeLocalStorage = {};
  var storage; 

  // If Storage exists we modify it to write to our fakeLocalStorage object instead. 
  // If Storage does not exist we create an empty object. 
  if (window.Storage && window.localStorage) {
    storage = window.Storage.prototype; 
  } else {
    // We don't bother implementing a fake Storage object
    window.localStorage = {}; 
    storage = window.localStorage; 
  }

  // For older IE
  if (!window.location.origin) {
    window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: '');
  }

  var dispatchStorageEvent = function(key, newValue) {
    var oldValue = (key == null) ? null : storage.getItem(key); // `==` to match both null and undefined
    var url = location.href.substr(location.origin.length);
    var storageEvent = document.createEvent('StorageEvent'); // For IE, http://stackoverflow.com/a/25514935/1214183

    storageEvent.initStorageEvent('storage', false, false, key, oldValue, newValue, url, null);
    window.dispatchEvent(storageEvent);
  };

  storage.key = function(i) {
    var key = Object.keys(fakeLocalStorage)[i];
    return typeof key === 'string' ? key : null;
  };

  storage.getItem = function(key) {
    return typeof fakeLocalStorage[key] === 'string' ? fakeLocalStorage[key] : null;
  };

  storage.setItem = function(key, value) {
    dispatchStorageEvent(key, value);
    fakeLocalStorage[key] = String(value);
  };

  storage.removeItem = function(key) {
    dispatchStorageEvent(key, null);
    delete fakeLocalStorage[key];
  };

  storage.clear = function() {
    dispatchStorageEvent(null, null);
    fakeLocalStorage = {};
  };
};

// Example of how to use it
if (typeof window.localStorage === 'object') {
  // Safari will throw a fit if we try to use localStorage.setItem in private browsing mode. 
  try {
    localStorage.setItem('localStorageTest', 1);
    localStorage.removeItem('localStorageTest');
  } catch (e) {
    fakeLocalStorage();
  }
} else {
  // Use fake localStorage for any browser that does not support it.
  fakeLocalStorage();
}

Ia memeriksa apakah localStorage ada dan dapat digunakan dan dalam kasus negatif, itu menciptakan penyimpanan lokal palsu dan menggunakannya sebagai pengganti localStorage asli. Tolong beri tahu saya jika Anda membutuhkan informasi lebih lanjut.

Bogdan Mates
sumber