admin管理员组文章数量:1198728
I'm working on a deck building application for a card game I play. I'm using localStorage to save and retrieve decks. It seems to be working flawlessly in Chrome, but in Firefox it is working unreliably.
In FF, everything seems to work fine at first, the deck even persists through a reload. However, if I add a second deck and reload, it only finds the first deck. If I delete the first deck, it no longer finds anything.
All the local storage interaction is in scripts/vault.js, which I'll reproduce below. Am I doing something wrong?
vault = {};
vault.makeKey = function (s) {
return "deck:" + s;
};
vault.friendlyName = function(s) {
if (s.indexOf("deck:") === 0) {
return s.substring(5);
} else {
return s;
}
};
vault.store = function (deck, name) {
if (!window.localStorage) {
alert("This browser doesn't support local storage. You will be unable to save decks.");
return;
}
var key = vault.makeKey(name);
localStorage.setItem(key, deck.export());
};
vault.retrieve = function (key) {
deck.import(localStorage[key]);
};
vault.getDecks = function () {
var keys = Object.keys(localStorage),
out = [],
i,
k,
name = "";
for (i = 0; i < keys.length; i++) {
k = keys[i];
name = vault.friendlyName(k);
if (name !== k && localStorage[k]) {
out.push({name: name, key: k});
}
}
out.sort(function (a, b) {
return a.name > b.name ? 1 : -1;
});
return out;
};
vault.deleteDeck = function (key) {
localStorage.removeItem(key);
};
Basically, it seems like at some point the keys in localStorage get 'frozen' for lack of a better term; localStorage will behave correctly while I manipulate it, but as soon as I refresh the page it seems to revert to whichever state it got frozen in.
I'm working on a deck building application for a card game I play. I'm using localStorage to save and retrieve decks. It seems to be working flawlessly in Chrome, but in Firefox it is working unreliably.
In FF, everything seems to work fine at first, the deck even persists through a reload. However, if I add a second deck and reload, it only finds the first deck. If I delete the first deck, it no longer finds anything.
All the local storage interaction is in scripts/vault.js, which I'll reproduce below. Am I doing something wrong?
vault = {};
vault.makeKey = function (s) {
return "deck:" + s;
};
vault.friendlyName = function(s) {
if (s.indexOf("deck:") === 0) {
return s.substring(5);
} else {
return s;
}
};
vault.store = function (deck, name) {
if (!window.localStorage) {
alert("This browser doesn't support local storage. You will be unable to save decks.");
return;
}
var key = vault.makeKey(name);
localStorage.setItem(key, deck.export());
};
vault.retrieve = function (key) {
deck.import(localStorage[key]);
};
vault.getDecks = function () {
var keys = Object.keys(localStorage),
out = [],
i,
k,
name = "";
for (i = 0; i < keys.length; i++) {
k = keys[i];
name = vault.friendlyName(k);
if (name !== k && localStorage[k]) {
out.push({name: name, key: k});
}
}
out.sort(function (a, b) {
return a.name > b.name ? 1 : -1;
});
return out;
};
vault.deleteDeck = function (key) {
localStorage.removeItem(key);
};
Basically, it seems like at some point the keys in localStorage get 'frozen' for lack of a better term; localStorage will behave correctly while I manipulate it, but as soon as I refresh the page it seems to revert to whichever state it got frozen in.
Share Improve this question asked Dec 13, 2012 at 2:55 AsmorAsmor 5,1816 gold badges34 silver badges42 bronze badges 4- Can you make a jsfiddle.net demo? – Jared Farrish Commented Dec 13, 2012 at 3:00
- 1 I posted a link to the application itself in my first post. Here it is again: asmor.com/anr – Asmor Commented Dec 13, 2012 at 3:03
- Well, if it's in a fiddle, I could work with the code and check different things. It's not necessary, but it would make it more likely myself and some others would tinker with it to see if we can figure it out. – Jared Farrish Commented Dec 13, 2012 at 3:11
- I just tried for a bit to distill this down to something that could be posted on JSFiddle, but there's just too much going on. Particularly given that the behavior I'm seeing depends on doing particular things and then reloading the page... I just don't think it's a good fit for this. Thanks anyways, man. – Asmor Commented Dec 13, 2012 at 3:48
6 Answers
Reset to default 8I have run into this same problem a few times and at first I didn't notice the reason why it just couldn't read the localStorage, but I think I found a solution for that.
The localStorage operations are all synchronous and different browsers have certain quirks about how they handle them.
In your case, the problem seems to be that you're trying to read the localStorage before the DOM is ready. I tried it with Firebug and I added a breakpoint to the beginning of the vault.js file and reload the page and when the code breaks, I check the dom-tab and find the localStorage property, and there it is - full list of stored values. When I removed the breakpoint and reloaded the page, they were all gone once the page was loaded.
This might be a bug in Firefox or other browsers just initialize the localStorage faster.
So, as a solution to your problem: try fetching the keys from localStorage AFTER the DOM is ready.
Though this is an old post but thought my findings might help. I was also facing the same issue so I went through this post, tried this and this is what I have noticed, in firefox if you try to do anything (even a localStorage.getItem) with localstorage before window.load it will remove everything from it and you will not have anything. So whatever you want to do set or get, do it after window.load.
Something like this
$( window ).load(function() {
//do whatever you want to do with localstorage
});
BTW I was trying to do some operations with localStorage at document.ready before this which was failing.
jylauril is on the right track, I think.
I've been playing with delays, and noticing some odd behavior.
As far as I can tell, it seems like if you touch localStorage at all before ALL JavaScript has completed execution, including JS doing setTimeout, localStorage will appear blank for that pageview. For example:
$(window).load(function () {
console.log("Waiting 10000ms", new Date());
setTimeout(setDeckSelect, 10000);
});
Firebug's console:
Waiting 10000ms Date {Thu Dec 13 2012 10:35:48 GMT-0500 (Eastern Standard Time)}
exec.js (line 191)
getDecks Date {Thu Dec 13 2012 10:35:58 GMT-0500 (Eastern Standard Time)}
vault.js (line 23)
>>> localStorage
0 items in Storage
I thought I might be on to something, but my theories so far have proven wrong. One weird thing I've noticed, though. Regardless of how long I wait, if I try to look up decks first, it will fail and local storage will be empty:
>>> vault.getDecks()
[]
>>> localStorage
0 items in Storage
But if I do those in the opposite order...
>>> localStorage
8 items in Storage deck:dfs=
"{"identity":"MakingNews","cards":{}}", deck:ngrngfrn= "{"identity":"BuildingaBetterWorld","cards":{}}", deck:sdfgshsh= "{"identity":"MakingNews","cards":{}}", deck:sdfgdgdfg= "{"identity":"MakingNews","cards":{}}", deck:dfgdfgas= "{"identity":"EngineeringtheFuture","cards":{}}", deck:sdfsga= "{"identity":"MakingNews","cards":{}}", deck:gdgd= "{"identity":"MakingNews","cards":{}}", deck:gfsdfgsdfg= "{"identity":"BuildingaBetterWorld","cards":{}}"
>>> vault.getDecks()
[Object { name= "dfgdfgas", key= "deck:dfgdfgas"}, Object { name= "dfs", key= "deck:dfs"}, Object { name= "gdgd", key= "deck:gdgd"}, Object { name= "gfsdfgsdfg", key= "deck:gfsdfgsdfg"}, Object { name= "ngrngfrn", key= "deck:ngrngfrn"}, Object { name= "sdfgdgdfg", key= "deck:sdfgdgdfg"}, Object { name= "sdfgshsh", key= "deck:sdfgshsh"}, Object { name= "sdfsga", key= "deck:sdfsga"}]
If I log localStorage in the function, it works as well:
vault.getDecks = function () {
console.log(localStorage);
var keys = Object.keys(localStorage),
out = [],
i,
k,
name = "";
for (i = 0; i < keys.length; i++) {
k = keys[i];
name = vault.friendlyName(k);
if (name !== k && localStorage[k]) {
out.push({name: name, key: k});
}
}
out.sort(function (a, b) {
return a.name > b.name ? 1 : -1;
});
return out;
};
it works. If I void it, though...
vault.getDecks = function () {
// console.log(localStorage);
void localStorage;
var keys = Object.keys(localStorage),
out = [],
i,
k,
name = "";
for (i = 0; i < keys.length; i++) {
k = keys[i];
name = vault.friendlyName(k);
if (name !== k && localStorage[k]) {
out.push({name: name, key: k});
}
}
out.sort(function (a, b) {
return a.name > b.name ? 1 : -1;
});
return out;
};
It does not work. It also doesn't work if I remove the void keyword and just have localStorage on its own as a statement.
I don't know why, but console.log(localstorage) does seem to fix this, and I can call the localStorage whenever I want.
Really freaking weird.
EDIT: I found a slightly better solution. Calling the 'length' attribute of localStorage works as well.
vault.getDecks = function () {
//Weird hack to make FF load localStorage correctly...
localStorage.length;
var keys = Object.keys(localStorage),
out = [],
i,
k,
name = "";
for (i = 0; i < keys.length; i++) {
k = keys[i];
name = vault.friendlyName(k);
if (name !== k && localStorage[k]) {
out.push({name: name, key: k});
}
}
out.sort(function (a, b) {
return a.name > b.name ? 1 : -1;
});
return out;
};
This is a bit better in that it doesn't log anything...
Posting this here to help anyone that may be experiencing what I am now experiencing.
If using Firefox, once you refresh the page, you need to close and re-open the dev tools in order to see the new localStorage items.
When the page refreshes, the localStorage items that were there before show. If you close and re-open the dev tools, you can see the new set. Any changes made from that point on (until the next refresh) will update live.
Definitely a Firefox dev tools bug.
I've reported the bug here: https://bugzilla.mozilla.org/show_bug.cgi?id=1706710
// Edit 5 minutes later I can't reproduce it now. I'm not sure but I think it might have been due to a Firefox update. It updated just as I'd finished writing the bug report. Did I really discover a bug in Firefox 87 that got fixed in Firefox 88 10 minutes before I updated?!! Will report back here if it re-occurs.
Thank you so much Asmor!
You save me a lot of time.
I developed an app using Google Chrome. Everything was working as described in the API doc. But as soon as I started using it in Firefox, it became very unreliable.
I found out that if I update a localStorage item using setItem
, I had to refresh the page 5 or 6 times before the update gets applied to the item. I had the same issue with removeItem
.
I wrote a wrapper around all localStorage function. I'm probably calling length
too often, but at least it's working first try now. I do not need to refresh the page several times anymore.
function localStorageClear() {
localStorage.length;
window.localStorage.clear();
localStorage.length;
}
function localStorageGetItem(key) {
localStorage.length;
const item = window.localStorage.getItem(key);
localStorage.length;
return item;
}
function localStorageSetItem(key, item) {
localStorage.length;
window.localStorage.setItem(key, item);
localStorage.length;
}
function localStorageRemoveItem(key) {
localStorage.length;
window.localStorage.removeItem(key);
localStorage.length;
}
NOTE: I'm posting this as an "Answer" because it's too big for a comment.
• To ensure that localStorage data is made available consistently in all html pages: o Domain (local context) must be same. o Make sure to keep the << script >> tags identical in all Html files, o (Firefox only) make sure the onPageLoad is kept identical in all JavaScript files (added within html files), i.e. make sure to add same functions to PageLoadEvent.
本文标签: javascriptlocalStorage unreliable in FirefoxStack Overflow
版权声明:本文标题:javascript - localStorage unreliable in Firefox - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738583375a2101292.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论