Web uygulamamın ios safari özel taramada javascript hataları var:
JavaScript: Hata
Tanımsız
QUOTA_EXCEEDED_ERR: DOM İstisna 22: Depolamaya bir şeyler eklemek için girişimde bulunuldu ...
kodum:
localStorage.setItem('test',1)
Web uygulamamın ios safari özel taramada javascript hataları var:
JavaScript: Hata
Tanımsız
QUOTA_EXCEEDED_ERR: DOM İstisna 22: Depolamaya bir şeyler eklemek için girişimde bulunuldu ...
kodum:
localStorage.setItem('test',1)
Yanıtlar:
Görünüşe göre bu tasarım gereğidir. Safari (OS X veya iOS) özel tarama modundaymış gibi görünüyorlocalStorage kullanılabilir , ancak aramaya çalışmak setItembir istisna atar.
store.js line 73
"QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage that exceeded the quota."
Olan şey, pencere nesnesinin hala ortaya çıkmasıdır localStorage genel ad alanında çıkmasıdır, ancak aradığınızda setItembu istisna atılır. Yapılacak çağrılar removeItemyok sayıldı.
En basit düzeltmenin (henüz bu çapraz tarayıcıyı test etmeme rağmen) isLocalStorageNameSupported()bazı değerleri de ayarlayabileceğinizi test etmek için işlevi değiştirmek olduğuna inanıyorum .
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];için return true. Daha sonra localStorage kullanılabilirliğine bağlı olarak güvenli bir şekilde doğru veya yanlış döndüren bir işleve sahipsiniz. Örneğin:if (isLocalStorageNameSupported()) { /* You can use localStorage.setItem */ } else { /* you can't use localStorage.setItem */ }
Yukarıdaki bağlantıda yayınlanan düzeltme benim için çalışmadı. Bu şunu yaptı:
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 türetilmiştir
window.sessionStoragedoğru. Kesinlikle benim kodumda çalışır. Aslında gösterir misiniz düzeltme sen haberdar görünen sorununa.
isLocalStorageNameSupportedve kontrol ediyordum window.sessionStorage. Aynı sonuç ama biraz kafa karıştırıcı oldu. Cevap açıklığa kavuşturmak için düzenlendi.
Diğer yanıtlarda belirtildiği gibi, her zaman hem iOS hem de OS X'te Safari Özel Tarayıcı Modunda QuotaExceededError'u localStorage.setItem(veyasessionStorage.setItem ) çağrıldığında .
Bir çözüm, her kullanım örneğinde bir try / catch veya Modernizr kontrolü yapmaktırsetItem .
Ancak, JavaScript'in geri kalanının bozulmasını önlemek için, bu hatanın küresel olarak atılmasını durduran bir şim istiyorsanız, bunu kullanabilirsiniz:
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.');
}
}
Benim bağlamımda, sadece bir sınıf soyutlaması geliştirdi. Benim uygulama başlatıldığında, getStorage () çağırarak localStorage çalışıp çalışmadığını kontrol edin . Bu işlev ayrıca şunları döndürür:
Benim kodda asla doğrudan localStorage çağırmak. Ben buna cusSto küresel var, ben arayarak başlatıldı etmişti ) (getStorage .
Bu şekilde, özel tarama veya belirli Safari sürümleriyle çalışır
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();
Görünüşe göre Safari 11 davranışı değiştiriyor ve şimdi yerel depolama özel bir tarayıcı penceresinde çalışıyor. Yaşasın!
Safari gizli taramada başarısız olan web uygulamamız şimdi kusursuz çalışıyor. Chrome'un her zaman yerel depolamaya yazmaya izin veren özel tarama modunda iyi çalıştı.
Bu, Mayıs 2017'de yayınlanan 29 sürümü için Apple'ın Safari Teknoloji Önizleme sürüm notlarında ve WebKit sürüm notlarında belgelenmiştir .
özellikle:
Başkalarının cevaplarını genişletmek için, yeni değişkenleri ortaya çıkarmayan / eklemeyen kompakt bir çözüm. Tüm üsleri kapsamaz, ancak tek bir sayfa uygulamasının işlevsel kalmasını isteyen çoğu kişiye uygun olmalıdır (yeniden yükleme sonrasında veri kalıcılığına rağmen).
(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 = {};
};
}
})();
İyonik çerçeve (Angular + Cordova) kullanırken de aynı sorunu yaşadım. Bunun sorunu çözmediğini biliyorum, ancak yukarıdaki cevaplara dayanarak Açısal Uygulamalar için kod var. Safari'nin iOS sürümünde localStorage için geçici bir çözümünüz olacak.
İşte kod:
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);
}
}
}
]);
Kaynak: https://gist.github.com/jorgecasar/61fda6590dc2bb17e871
Kodlamanın tadını çıkarın!
İşte IIFE kullanan ve hizmetlerin tek tonlu olduğu gerçeğini kullanan AngularJS için bir çözüm .
Bu isLocalStorageAvailable, hizmet ilk enjekte edildiğinde derhal ayarlanmasına neden olur ve yerel depolamaya her erişilmesi gerektiğinde denetimin gereksiz yere çalıştırılmasını önler.
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');
}
};
}
]);
Bu repoyu desteklenmeyen veya devre dışı bırakılan tarayıcılara özellikler sessionStorageve localStorageözellikler sağlamak için oluşturdum .
Desteklenen tarayıcılar
Nasıl çalışır
Depolama türüyle özelliği algılar.
function(type) {
var testKey = '__isSupported',
storage = window[type];
try {
storage.setItem(testKey, '1');
storage.removeItem(testKey);
return true;
} catch (error) {
return false;
}
};
Kümeler StorageService.localStorageiçin window.localStoragedesteklenen veya bir çerez deposu oluşturur eğer. Kümeler StorageService.sessionStorageiçin window.sessionStoragedesteklenen veya SPA için hafıza depolama, sigara SPA için sesion özellikleri ile çerez depolama bir oluşturur eğer.
İşte bellek depolama alternatifi için bir Angular2 + servis versiyonu, Pierre Le Roux'un cevabına dayanarak bileşenlerinize enjekte edebilirsiniz.
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'da tam okuma ve yazma yerel paylaşım desteği
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);
Bu, anahtarlarınızın tüm tarayıcılarda ayarlandığından ve alındığından emin olur.
Sorun için bir yama oluşturdum. Tarayıcının localStorage veya sessionStorage'ı destekleyip desteklemediğini kontrol ediyorum. Değilse, depolama motoru Çerez olacaktır. Ancak olumsuz tarafı Cookie'nin çok küçük depolama belleğine sahip olmasıdır :(
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')
Kabul edilen cevap bazı durumlarda yeterli görünmemektedir.
localStorageVeya sessionStorageöğesinin desteklenip desteklenmediğini denetlemek için MDN'den aşağıdaki snippet'i kullanıyorum .
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);
}
}
Bu snippet'i şu şekilde kullanın ve örneğin çerez kullanarak geri dönün:
if (storageAvailable('localStorage')) {
// Yippee! We can use localStorage awesomeness
}
else {
// Too bad, no localStorage for us
document.cookie = key + "=" + encodeURIComponent(value) + expires + "; path=/";
}
Depolama alanı kullanılabilirliğini ve el ile uygulanan bir MemoryStorage'a geri dönüşü denetlemek için bu snippet'i kullanan geri dönüş paketini yaptım .
import {getSafeStorage} from 'fallbackstorage'
getSafeStorage().setItem('test', '1') // always work
var mod = 'test';
try {
sessionStorage.setItem(mod, mod);
sessionStorage.removeItem(mod);
return true;
} catch (e) {
return false;
}
Aşağıdaki komut dosyası sorunumu çözdü:
// 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();
}
LocalStorage'ın olup olmadığını kontrol eder ve kullanılabilir ve negatif durumda, sahte bir yerel depolama alanı oluşturur ve orijinal localStorage yerine kullanır. Daha fazla bilgiye ihtiyacınız olursa lütfen bize bildirin.