marcuswestin / store.js

Cross-browser storage for all use cases, used across the web.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

IE LocalStorage.setItem bug with compression

lianee opened this issue · comments

Using store.everything.min.js 2.0.12, Edge (IE11 also) throw an exception "SCRIPT87: Invalid argument" with the following code:

var x = [
  {"id":"10","keys":"dev"}
];
store.set('test', x);

crash happens line 22 of localStorage.js

It seems that there's a char in the compressed string that IE doesn't like too much. No problem with Chrome or Firefox.

jsfiddle

I'm having the same issue on Edge. Since I had to fix it ASAP (it was blocking my checkout page for some users) I added the following patch right after including store.js:

try
{
    store.set("__test_store_", [{"id":"10","keys":"dev"}])
}
catch (e)
{
    console.warn("Store fallback!");
    store = {
        get: function(key)
        {
            return JSON.parse(localStorage.getItem(key));
        },
        set: function(key, val)
        {
            localStorage.setItem(key, JSON.stringify(val));
        },
    }
}

Its not a good solution but its better than nothing for now..
Hope this problem will have a solution soon.

Excellent, thank you for the patch!

I made some adjustments for my use case scenario to hook the func and attempt to use it preferentially

window.storageReadyCallback = function(storage) {
	// internet explorer fallback, due to poor browser code by microsoft.
	try {
		storage.set("__test_store_", [{"id":"10","keys":"dev"}])
	}
	catch (e) {
		console.warn("Store fallback!");
		storage._get = storage.get;
		storage.get = function(key) {
			var r=null;
			try {
				r = storage._get(key);
			} catch (E) {
				r = JSON.parse(localStorage.getItem(key));
			}
			return r;
		};
		storage._set = storage.set;
		storage.set = function(key, val) {
			try {
				storage._set(key, val);
			} catch (E) {
				localStorage.setItem(key, JSON.stringify(val));
			}
		}
	}
};

This is probably a little old but just found out from LZString you can do the following (code from http://pieroxy.net/blog/pages/lz-string/guide.html):

var string = "This is my compression test.";
alert("Size of sample is: " + string.length);
var compressed = LZString.compressToUTF16(string);
alert("Size of compressed sample is: " + compressed.length);
localStorage.setItem("myData",compressed);
(...)
string = LZString.decompressFromUTF16(localStorage.getItem("myData"));
alert("Sample is: " + string);