html5 localStorage-Fehler bei Safari: "QUOTA_EXCEEDED_ERR: DOM-Ausnahme 22: Es wurde versucht, dem Speicher etwas hinzuzufügen, das das Kontingent überschritten hat."

133

Meine Webanwendung hat Javascript-Fehler beim privaten Surfen in ios safari:

JavaScript: Fehler

nicht definiert

QUOTA_EXCEEDED_ERR: DOM-Ausnahme 22: Es wurde versucht, dem Speicher etwas hinzuzufügen ...

Mein Code:

localStorage.setItem('test',1)
Leiyonglin
quelle
Verwenden Sie eine Funktion, die erkennt, dass Tests für dieses spezielle Problem durchgeführt werden . Wenn kein Speicher verfügbar ist, sollten Sie localStorage mit memoryStorage kombinieren . Haftungsausschluss: Ich bin der Autor der verlinkten Pakete
Stijn de Witt
4
Hallo Leute, ich helfe bei der Wartung von safaridriver. Dieses Problem ist ein langjähriger Fehler in WebKit, der kürzlich behoben wurde. Lokaler Speicher und Sitzungsspeicher funktionieren jetzt in Safari 10.1 und höher. Dieser Fix wirkt sich auf den normalen privaten Browsermodus und den Automatisierungsmodus (von WebDriver verwendet) aus.
Brian Burg

Antworten:

183

Anscheinend ist dies beabsichtigt. Wenn sich Safari (OS X oder iOS) im privaten Browsermodus befindet, scheint localStoragees verfügbar zu sein, aber der Versuch, einen Anruf zu tätigen, setItemlöst eine Ausnahme aus.

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

Was passiert ist, dass das Fensterobjekt immer noch localStorageim globalen Namespace verfügbar gemacht wird, aber wenn Sie aufrufen setItem, wird diese Ausnahme ausgelöst. Alle Anrufe an removeItemwerden ignoriert.

Ich glaube, die einfachste Lösung (obwohl ich diesen Cross-Browser noch nicht getestet habe) wäre, die Funktion isLocalStorageNameSupported()zu ändern, um zu testen, ob Sie auch einen Wert festlegen können.

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
quelle
1
Dies muss nicht unbedingt auf den Inkognito-Modus zurückzuführen sein ... obwohl ich denke, dass das OP nicht mehrere Megabyte Daten speichern wollte;)
Christoph
5
Schauen Sie sich diese Übersicht an, die eine kurze Geschichte der Erkennung lokaler Speicher durch Paul Irish zeigt.
Mottie
4
Ist es für den Fall, dass localStorage in Safari nicht funktioniert, die nächstbeste Option, alles in Cookies zu speichern?
Will Hitchcock
5
Ähnlich wie bei dem Paul Irish Beispiel, schlage ich vor Wechsel return localStorageName in win && win[localStorageName];zu return true. Dann haben Sie eine Funktion, die je nach Verfügbarkeit von localStorage sicher true oder false zurückgibt. Zum Beispiel:if (isLocalStorageNameSupported()) { /* You can use localStorage.setItem */ } else { /* you can't use localStorage.setItem */ }
DrewT
1
Es wurde überprüft, dass das Problem nicht nur beim privaten Fenster, sondern auch beim normalen Safari-Fenster auftritt.
Codemirror
38

Das auf dem obigen Link veröffentlichte Update hat bei mir nicht funktioniert. Dies tat:

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

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

Cyberwombat
quelle
20
Gibt es einen bestimmten Grund, warum Sie (und @KingKongFrog) window.sessionStorage verwenden, um festzustellen, ob Sie in localStorage schreiben können, oder ob wir uns in einem seltsamen Tippfehlerzyklus befinden?
Yetti
@Yetti Wenn Sie einen Tippfehler bemerkt haben, warum korrigieren Sie ihn nicht entweder in einer Bearbeitung oder in Ihrem Kommentar? Soweit mir bekannt window.sessionStorageist richtig. Es funktioniert sicherlich in meinem Code. Bitte weisen Sie tatsächlich auf die Lösung des Problems hin, über das Sie anscheinend Bescheid wissen.
Novocaine
7
@Novocaine Mein Kommentar wies darauf hin, dass sie sessionStorage in einer Funktion verwenden, die vorhanden ist, um nach localStorage-Unterstützung zu suchen. Ja, es wird wahrscheinlich immer noch funktionieren, aber wie geschrieben ist der Funktionsname für das, was tatsächlich getestet wird, irreführend. Ich habe mich entschieden zu kommentieren, anstatt zu bearbeiten, weil ich dachte, ich würde etwas vermissen und hoffte, von diesen Jungs zu lernen. Leider haben sie nicht geantwortet oder eine Korrektur vorgenommen, also sind wir hier.
Yetti
3
@ Yetti Danke für die Klarstellung. Ich verstehe, worüber du jetzt warst. ; -]
Novocaine
2
@DawsonToth nein, das lag daran, dass ich die Funktion aufgerufen isLocalStorageNameSupportedund überprüft habe window.sessionStorage. Gleiches Endergebnis, aber etwas verwirrend. Die Antwort wurde zur Verdeutlichung bearbeitet.
Cyberwombat
25

Wie in anderen Antworten erwähnt, erhalten Sie den QuotaExceededError immer im privaten Safari-Browsermodus unter iOS und OS X, wenn localStorage.setItem(odersessionStorage.setItem ) aufgerufen wird.

Eine Lösung besteht darin , in jedem Verwendungsfall einen Try / Catch- oder Modernizr-Check durchzuführensetItem .

Wenn Sie jedoch einen Shim möchten, der diesen Fehler einfach global verhindert, um zu verhindern, dass der Rest Ihres JavaScript beschädigt wird, können Sie Folgendes verwenden:

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
quelle
11

In meinem Kontext habe ich gerade eine Klassenabstraktion entwickelt. Wenn meine Anwendung gestartet wird, überprüfe ich, ob localStorage funktioniert, indem ich getStorage () aufrufe . Diese Funktion gibt auch zurück:

  • entweder localStorage, wenn localStorage funktioniert
  • oder eine Implementierung einer benutzerdefinierten Klasse LocalStorageAlternative

In meinem Code rufe ich localStorage nie direkt auf. Ich rufe cusSto global var auf, das ich durch Aufrufen von getStorage () initialisiert hatte .

Auf diese Weise funktioniert es mit privatem Surfen oder bestimmten Safari-Versionen

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
quelle
2
Danke Pierre, deine Antwort hat mich inspiriert. Am Ende habe ich alles in einem schönen Modul namens Memorystorage verpackt . Open Source natürlich. Wenn Sie Probleme mit anderen Personen haben, lesen Sie es, es könnte Ihnen helfen.
Stijn de Witt
Ha. Ich habe das Gleiche getan (unabhängig). Verwenden Sie weiterhin die Variable localStorage (zumindest in Safari können Sie die Variable localStorage nicht überschreiben (sie ist schreibgeschützt), aber Sie können setItem / removeItem / getItem neu zuweisen).
Ruben Martinez Jr.
@StijndeWitt, wie kann ich auf meine Speicherwerte auf anderen Seiten zugreifen? Zum Beispiel habe ich dies in meiner helper.php var store = MemoryStorage ('my-app'); store.setItem ('myString', 'Hallo MemoryStorage!'); Ich möchte auf den Wert von myString in lecture.php zugreifen. Ich habe versucht, Memorystorage auf der Seite zu initiieren, aber es wird immer noch ein leeres Objekt angezeigt.
user1149244
@ user1149244 Memorystorage ist lokal auf der Seite. Es simuliert die Web Storage-API und kann als Fallback verwendet werden, wenn localStorage und sessionStorage nicht verfügbar sind. Die Daten werden jedoch nur im Seitenspeicher gespeichert (daher der Name). Wenn Daten seitenübergreifend gespeichert werden müssen, können Cookies hilfreich sein. Die Datenmenge, die gespeichert werden kann, ist jedoch sehr begrenzt. Ansonsten kann nicht viel getan werden.
Stijn de Witt
2
@ user1149244 Speichert das nicht angeblich die Werte im Browser? Nein, das kann es nicht. Es gibt drei Möglichkeiten, um clientseitige Inhalte von einer Seitenaktualisierung zur anderen zu speichern: Cookies, sessionStorage / localStorage und IndexedDB. Die letzten beiden sind relativ neu. sessionStorage und localStorage werden weitgehend unterstützt, sodass Sie sie praktisch überall verwenden können. außer im privaten Browsermodus , um den es in diesem Problem geht. Programme sind kaputt gegangen, weil kein Speicher vorhanden war. memorystorage bietet nur einen Fallback, der immer funktioniert, während er auf der Seite ist, aber die Daten nicht speichern kann. Es ist ein Stummel. Aber kein Fehler.
Stijn de Witt
5

Es scheint, dass Safari 11 das Verhalten ändert und der lokale Speicher jetzt in einem privaten Browserfenster funktioniert. Hurra!

Unsere Web-App, die früher beim privaten Surfen in Safari fehlgeschlagen ist, funktioniert jetzt einwandfrei. Im privaten Browsermodus von Chrome hat es immer gut funktioniert, da immer in den lokalen Speicher geschrieben werden konnte.

Dies ist in den Versionshinweisen zu Safari Technology Preview von Apple - und den Versionshinweisen zu WebKit - für Version 29 dokumentiert , die im Mai 2017 veröffentlicht wurde.

Speziell:

  • QuotaExceededError beim Speichern in localStorage im privaten Browsermodus oder in WebDriver-Sitzungen behoben - r215315
karlbecker_com
quelle
4

Um die Antworten anderer zu erweitern, finden Sie hier eine kompakte Lösung, die keine neuen Variablen verfügbar macht / hinzufügt. Es deckt nicht alle Basen ab, sollte jedoch für die meisten Benutzer geeignet sein, die nur möchten, dass eine App mit nur einer Seite funktionsfähig bleibt (obwohl nach dem erneuten Laden keine Datenbeständigkeit besteht).

(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
quelle
3

Ich hatte das gleiche Problem mit dem Ionic Framework (Angular + Cordova). Ich weiß, dass dies das Problem nicht löst, aber es ist der Code für Angular Apps, der auf den obigen Antworten basiert. Sie haben eine kurzlebige Lösung für localStorage für die iOS-Version von Safari.

Hier ist der Code:

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);
            }
        }
    }
]);

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

Viel Spaß beim Codieren!

Jorgecasar
quelle
1
Obwohl dies die Frage nicht beantwortet, ist dies das erste, was auftauchte, als ich das Problem googelte. Der nächste Schritt wäre gewesen, nach der Lösung für Angular zu suchen, aber dank dieses Kommentars muss ich nicht woanders hingehen. Vielleicht wird die Frage nicht direkt beantwortet, aber es war großartig für mich und wahrscheinlich für andere!
Leonard
2

Hier ist eine Lösung für AngularJS, die ein IIFE verwendet und die Tatsache nutzt, dass Dienste Singletons sind .

Dies führt dazu, isLocalStorageAvailabledass die Einstellung sofort beim ersten Injizieren des Dienstes erfolgt und die Prüfung nicht unnötig ausgeführt wird, wenn auf den lokalen Speicher zugegriffen werden muss.

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');
      }
    };
  }
]);
Pier-Luc Gendreau
quelle
1

Ich habe gerade diese Repo zur Verfügung zu stellen sessionStorageund localStoragebiete für nicht unterstützten oder fähigen Browser.

Unterstützte Browser

  • IE5 +
  • Chrome alle Versionen
  • Mozilla alle Versionen
  • Yandex alle Versionen

Wie es funktioniert

Es erkennt die Funktion mit dem Speichertyp.

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

Legt fest StorageService.localStorage, window.localStorageob es unterstützt wird oder ob ein Cookie-Speicher erstellt wird. Legt fest StorageService.sessionStorage, window.sessionStorageob es unterstützt wird oder einen In-Memory-Speicher für SPA erstellt, einen Cookie-Speicher mit Sitzungsfunktionen für Nicht-SPA.

Ahmet Can Güven
quelle
1
Vielen Dank, Ihre Bibliothek hat sehr geholfen!
Mathieu
1

Hier ist eine Angular2 + -Dienstversion für die Speicheralternative, die Sie basierend auf der Antwort von Pierre Le Roux einfach in Ihre Komponenten einfügen können.

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
quelle
0

Verwenden Sie es nicht, wenn es nicht unterstützt wird. Um die Unterstützung zu überprüfen, rufen Sie einfach diese Funktion auf

Freigeben in Es6 Lesen und Schreiben von localStorage-Beispiel mit Support-Prüfung

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);

Dadurch wird sichergestellt, dass Ihre Schlüssel in allen Browsern richtig eingestellt und abgerufen werden.

Tarandeep Singh
quelle
0

Ich habe einen Patch für das Problem erstellt. Ich überprüfe einfach, ob der Browser localStorage oder sessionStorage unterstützt oder nicht. Wenn nicht, ist die Speicher-Engine Cookie. Aber die negative Seite ist, dass Cookies einen sehr kleinen Speicher haben :(

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.
quelle
0

Die akzeptierte Antwort scheint in mehreren Situationen nicht angemessen zu sein.

Um zu überprüfen, ob die localStorageoder sessionStorageunterstützt werden, verwende ich das folgende Snippet von 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);
    }
}

Verwenden Sie dieses Snippet wie folgt und greifen Sie beispielsweise auf Cookies zurück:

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

Ich habe das Fallbackstorage- Paket erstellt, das dieses Snippet verwendet, um die Speicherverfügbarkeit zu überprüfen und auf einen manuell implementierten MemoryStorage zurückzugreifen.

import {getSafeStorage} from 'fallbackstorage'

getSafeStorage().setItem('test', '1') // always work
transang
quelle
-1
var mod = 'test';
      try {
        sessionStorage.setItem(mod, mod);
        sessionStorage.removeItem(mod);
        return true;
      } catch (e) {
        return false;
      }
Naim DOGAN
quelle
1
Vielleicht möchten Sie ein paar Worte zur Erklärung hinzufügen?
Bogl
-2

Das folgende Skript hat mein Problem gelöst:

// 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();
}

Es prüft, ob localStorage vorhanden ist und verwendet werden kann, und im negativen Fall erstellt es einen gefälschten lokalen Speicher und verwendet ihn anstelle des ursprünglichen localStorage. Bitte lassen Sie mich wissen, wenn Sie weitere Informationen benötigen.

Bogdan Kumpels
quelle