मेरे वेबएप में आईओएस सफारी निजी ब्राउज़िंग में जावास्क्रिप्ट त्रुटियां हैं:
जावास्क्रिप्ट: त्रुटि
अपरिभाषित
QUOTA_EXCEEDED_ERR: DOM अपवाद 22: संग्रहण में कुछ जोड़ने का प्रयास किया गया ...
मेरा कोड:
localStorage.setItem('test',1)
मेरे वेबएप में आईओएस सफारी निजी ब्राउज़िंग में जावास्क्रिप्ट त्रुटियां हैं:
जावास्क्रिप्ट: त्रुटि
अपरिभाषित
QUOTA_EXCEEDED_ERR: DOM अपवाद 22: संग्रहण में कुछ जोड़ने का प्रयास किया गया ...
मेरा कोड:
localStorage.setItem('test',1)
जवाबों:
जाहिरा तौर पर यह डिजाइन द्वारा है। जब सफारी (ओएस एक्स या आईओएस) निजी ब्राउज़िंग मोड में होता है, तो ऐसा प्रतीत होता है जैसे localStorage
उपलब्ध है, लेकिन setItem
थ्रो को अपवाद कहने की कोशिश कर रहा है।
store.js line 73
"QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage that exceeded the quota."
क्या होता है कि विंडो ऑब्जेक्ट अभी भी localStorage
वैश्विक नेमस्पेस में उजागर होता है , लेकिन जब आप कॉल करते हैं setItem
, तो यह अपवाद फेंक दिया जाता है। किसी भी कॉल को removeItem
नजरअंदाज किया जाता है।
मेरा मानना है कि सरलतम फिक्स (हालांकि मैंने अभी तक इस क्रॉस ब्राउज़र का परीक्षण नहीं किया है) यह परीक्षण को बदलने के लिए होगा isLocalStorageNameSupported()
कि आप कुछ मूल्य भी निर्धारित कर सकते हैं।
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;
}
}
return localStorageName in win && win[localStorageName];
जाए return true
। फिर आपके पास एक फ़ंक्शन है जो स्थानीयस्टोरेज उपलब्धता के आधार पर सही या गलत रिटर्न करता है। उदाहरण के लिए:if (isLocalStorageNameSupported()) { /* You can use localStorage.setItem */ } else { /* you can't use localStorage.setItem */ }
उपरोक्त लिंक पर पोस्ट किए गए फ़िक्स ने मेरे लिए काम नहीं किया। यह किया:
function isLocalStorageNameSupported() {
var testKey = 'test', storage = window.localStorage;
try {
storage.setItem(testKey, '1');
storage.removeItem(testKey);
return true;
} catch (error) {
return false;
}
}
Http://m.cg/post/13095478393/detect-private-browsing-mode-in-mobile-safari-on-ios5 से व्युत्पन्न
window.sessionStorage
है सही है। यह निश्चित रूप से मेरे कोड में काम करता है। कृपया वास्तव में उस समस्या के समाधान को इंगित करें जिसके बारे में आप जानते हैं।
isLocalStorageNameSupported
था और चेक कर रहा था window.sessionStorage
। एक ही अंतिम परिणाम लेकिन थोड़ा भ्रमित था। जवाब स्पष्ट करने के लिए संपादित किया गया था।
जैसा कि अन्य उत्तरों में उल्लेख किया गया है, आपको हमेशा localStorage.setItem
(या sessionStorage.setItem
) कॉल करने पर iOS और OS X दोनों पर सफारी प्राइवेट ब्राउज़र मोड में QuotaExceededError मिलेगा ।
एक समाधान का उपयोग करने के प्रत्येक उदाहरण में एक कोशिश / पकड़ या आधुनिकीकरण की जाँच करना है setItem
।
हालाँकि, यदि आप एक ऐसी शिम चाहते हैं, जो विश्व स्तर पर इस त्रुटि को रोकती है, तो अपने जावास्क्रिप्ट को टूटने से रोकने के लिए, आप इसका उपयोग कर सकते हैं:
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.');
}
}
मेरे संदर्भ में, बस एक वर्ग अमूर्तता विकसित की है। जब मेरा एप्लिकेशन लॉन्च किया जाता है, तो मैं जांचता हूं कि क्या लोकलस्टोरेज गेटस्टोरेज () कहकर काम कर रहा है । यह समारोह भी लौटा:
मेरे कोड में मैं कभी भी लोकलस्टोरेज को सीधे कॉल नहीं करता। मैं cusSto को वैश्विक संस्करण कहता हूं , मैंने गेटस्टेज () को कॉल करके आरंभ किया था ।
इस तरह, यह निजी ब्राउज़िंग या विशिष्ट सफारी संस्करणों के साथ काम करता है
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();
ऐसा लगता है कि सफारी 11 व्यवहार में परिवर्तन करता है, और अब स्थानीय भंडारण एक निजी ब्राउज़र विंडो में काम करता है। हुर्रे!
हमारा वेब ऐप जो सफारी प्राइवेट ब्राउजिंग में फेल हो जाता था, अब बेधड़क काम करता है। Chrome के निजी ब्राउज़िंग मोड में यह हमेशा ठीक रहता है, जिसने हमेशा स्थानीय भंडारण को लिखने की अनुमति दी है।
यह Apple के सफारी टेक्नोलॉजी प्रीव्यू रिलीज नोट्स - और वेबकिट रिलीज़ नोट्स - में रिलीज़ 29 के लिए प्रलेखित है , जो मई 2017 में था।
विशेष रूप से:
दूसरों के उत्तरों पर विस्तार करने के लिए, यहां एक कॉम्पैक्ट समाधान है जो किसी भी नए चर को उजागर / जोड़ नहीं है। यह सभी आधारों को कवर नहीं करता है, लेकिन यह ज्यादातर लोगों के लिए उपयुक्त होना चाहिए, जो केवल एक ही पृष्ठ एप्लिकेशन को कार्यशील रखना चाहते हैं (पुनः लोड के बाद कोई डेटा दृढ़ता नहीं होने के बावजूद)।
(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 = {};
};
}
})();
Ionic फ्रेमवर्क (कोणीय + कॉर्डोवा) का उपयोग करने में मुझे यही समस्या थी। मुझे पता है कि यह समस्या को हल नहीं करता है, लेकिन यह ऊपर के उत्तरों के आधार पर कोणीय एप्लिकेशन के लिए कोड है। आपके पास सफारी के आईओएस संस्करण पर स्थानीयस्टोरेज के लिए एक अल्पकालिक समाधान होगा।
यहाँ कोड है:
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);
}
}
}
]);
स्रोत: https://gist.github.com/jorgecasar/61fda6590dc2bb17e871
अपने कोडिंग का आनंद लें!
यहाँ एक IIFE का उपयोग करके AngularJS के लिए एक समाधान है और इस तथ्य का लाभ उठाते हुए कि सेवाएँ एकल हैं ।
में यह परिणाम isLocalStorageAvailable
स्थापित किया जा रहा तुरंत जब सेवा पहले इंजेक्ट किया जाता है और बेकार में जांच हर बार स्थानीय भंडारण जरूरतों को एक्सेस किए जाने चल टाल।
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');
}
};
}
]);
मैं सिर्फ प्रदान करने के लिए और इस रेपो बनायाsessionStorage
localStorage
असमर्थित या अक्षम ब्राउज़रों के लिए सुविधाएं सुविधाएँ ।
समर्थित ब्राउज़र
यह काम किस प्रकार करता है
यह स्टोरेज टाइप के साथ फीचर का पता लगाता है।
function(type) {
var testKey = '__isSupported',
storage = window[type];
try {
storage.setItem(testKey, '1');
storage.removeItem(testKey);
return true;
} catch (error) {
return false;
}
};
सेट StorageService.localStorage
करने के लिए window.localStorage
अगर यह समर्थित या एक कुकी भंडारण बनाता है। सेट StorageService.sessionStorage
करने के लिए window.sessionStorage
अगर यह समर्थित या स्पा के लिए स्मृति भंडारण, गैर एसपीए के लिए sesion सुविधाओं के साथ कुकी स्टोरेज में एक बनाता है।
यहां मेमोरी स्टोरेज विकल्प के लिए एक Angular2 + सेवा संस्करण है, आप पियरे ले रॉक्स के उत्तर के आधार पर अपने घटकों में इंजेक्ट कर सकते हैं।
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);
}
}
Es6 में साझा करना पूर्ण पढ़ना और समर्थन जांच के साथ localStorage उदाहरण लिखना
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);
यह सुनिश्चित करेगा कि आपकी चाबियाँ सभी ब्राउज़रों पर ठीक से सेट और पुनर्प्राप्त की गई हैं।
मैंने मुद्दे के लिए एक पैच बनाया है। बस मैं जाँच रहा हूँ कि ब्राउज़र लोकलस्टोरेज या सेशनस्टोरेज को सपोर्ट करता है या नहीं। यदि नहीं तो भंडारण इंजन कुकी होगा। लेकिन नकारात्मक पक्ष कुकी की बहुत कम भंडारण मेमोरी है :(
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')
स्वीकृत उत्तर कई स्थितियों में पर्याप्त नहीं लगता है।
यह जाँचने के लिए कि क्या समर्थित हैं localStorage
या नहीं sessionStorage
, मैं एमडीएन से निम्नलिखित स्निपेट का उपयोग करता हूं ।
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);
}
}
इस तरह इस स्निपेट का उपयोग करें, और उदाहरण के लिए, कुकी का उपयोग करके वापस आना:
if (storageAvailable('localStorage')) {
// Yippee! We can use localStorage awesomeness
}
else {
// Too bad, no localStorage for us
document.cookie = key + "=" + encodeURIComponent(value) + expires + "; path=/";
}
मैंने फॉलबैकस्टोरेज पैकेज बनाया है जो स्टोरेज की उपलब्धता की जांच करने के लिए इस स्निपेट का उपयोग करता है और मैन्युअल रूप से कार्यान्वित मेमोरीस्टेज में वापसी करता है।
import {getSafeStorage} from 'fallbackstorage'
getSafeStorage().setItem('test', '1') // always work
निम्नलिखित स्क्रिप्ट ने मेरी समस्या हल कर दी:
// 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();
}
यह जाँचता है कि क्या लोकलस्टोरेज मौजूद है और इसका उपयोग किया जा सकता है और नकारात्मक स्थिति में, यह एक नकली स्थानीय स्टोरेज बनाता है और इसका उपयोग मूल स्टोरेज के बजाय करता है। अगर आपको और जानकारी चाहिए तो कृपया मुझे बताएं।