Git Product home page Git Product logo

store.js's People

Contributors

aaronllanos avatar akx avatar alias-mac avatar alrick avatar benrudolph avatar bhague1281 avatar blq avatar bokub avatar christophehurpeau avatar gregwebs avatar jackfranklin avatar jakobud avatar joeduncan avatar jrbotros avatar kappuccino avatar krizzu avatar lfac-pt avatar m19c avatar marcuswestin avatar matthewmueller avatar mjpizz avatar mortonfox avatar mosch avatar per-gron avatar popomore avatar prayagverma avatar rmg avatar stevenblack avatar w33ble avatar whitehat101 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

store.js's Issues

Synchronisation with server

Hi,

I would be interested in implementing 'sync with server' functionality for a Key/Value store such as Redis/Memcached, possibly even MongoDB/CouchDB too.

Why? One of the main uses of localStorage is to hold user inputted data locally incase of an unexpected interrupt that forces the browser or input device to crash. Holding the data in localStorage then allows the user to quickly resume to what they were doing without loosing already inputted data.

I feel providing a sync helper method that produces a PUT/POST RESTful request to a URL would be fantastic functionality for this library.

Jacob.

Feature request: Encrypted storage

Goal

Use encryption for storing data for non-public app areas.

Description

As far as I know, browsers store DOM storage on disk in unencrypted files, DOM storage is accessible from all domain paths (except IE UserData) and doesn't expire.

This may be considered as security issue on shared workstations in cases when client-side app doesn't clear user data (browser crash/ closed window) or browser decides to keep them (temporary files).

I see the simplest solution in encrypting storage data after serializing to JSON and decrypt before deserializing.

It's up to the developer to come up with idea how to obtain secure key/ token; assuming encrypted storage makes sense for non-public areas (user is logged in), one can possibly use server-side unique session token.
Once server-side session expires, token is not available anymore. When there is no token, previously saved data theoretically become undecryptable junk (and may be removed client-side on next execution).

This should limit access to user data.

Drawback: Storage values take quite more space (depends on encoding);

Inspiration: dojo.storage.encrypted

Implementation

Configuration for Crypto.js, but any crypt library with methods encrypt( value ) and decrypt( encrypted ) should work:

store.crypt = {
    key: App.token, // ie. 'c015dc1d6028a6815ac944c8512c10db',
    encrypt: function( plaintext ) {
        return CryptoJS.AES.encrypt( plaintext, this.key ).toString();
    },
    decrypt: function( encrypted ) {
        return CryptoJS.AES.decrypt( encrypted, this.key ).toString( CryptoJS.enc.Utf8 );
    }
}

Proposed changes to store.js code (didn't test):

store.serialize = function(value) {

    var serialized = JSON.stringify( value );

    if ( store.crypt ) { serialized = store.crypt.encrypt( serialized ); }

    return serialized;
}


store.deserialize = function(value) {

    if ( typeof value !== 'string' ) { return undefined; }

    if ( store.crypt )
    {
        try {
            value = store.crypt.decrypt( value );
        } catch (e) {
            return undefined;
        }
    }

    return JSON.parse( value );
}

I'd like to discuss this idea with more proficient developers as I don't have much experience with client-side encryption.

Issues with Safari (iOS and Mac) when in Private Browsing mode

It seems Private Browsing makes localStorage read only:
http://spin.atomicobject.com/2013/01/23/ios-private-browsing-localstorage/

When loading store.js, I get this error:
QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage that exceeded the quota.

I saw these lines in the lib:

try {
  store.set(namespace, namespace)
  if (store.get(namespace) != namespace) { store.disabled = true }
  store.remove(namespace)
} catch(e) {
  store.disabled = true
}

Maybe there's something to improve there…

set and get w/ JSON enhancement

Would be nice to find a way to use JSON.stringify & JSON.parse internally to allow for something like the following:

store.set('user', {name: 'jeff'});
var myobj = store.get('user');

set could detect whether the value is an object and then JSON.stringify
get could attempt a JSON.parse and simply return a string on an exception.

In any case, nice lib :-)

IE6/IE7 data storage cannot be shared among pages on different paths of the same domain

It appears that the userData method used in IE6 and IE7 only stores data associated with the current path, i.e. data stored when on www.example.com/path1 is not accessible from www.example.com/path2 and vice-versa. Additionally, data stored at www.example.com/path1 is not available to subpaths (e.g. www.example.com/path1/subpath1).

There may be a way around this using the document body of an ActiveXObject("htmlfile") instead of the current document body. In the meantime, this caveat seems important enough to note in the README for IE6/IE7 storage.

Any plans for FireFox 4 support?

I'm aware that it isn't listed under supported browsers.

But I'm still hoping for support. It DOES work for Chrome 11 and that's not listed either.

I do get the following when running tests.html in FireFox4:
tests for store.js
first pass bad assert: Tests should not throw: "{"message":"store is not defined","fileName":"file:///Users/Jocke/Sites/peka/test.html","lineNumber":33,"stack":"doFirstPass()@file:///Users/Jocke/Sites/peka/test.html:33\u000a()@file:///Users/Jocke/Sites/peka/test.html:95\u000a@file:///Users/Jocke/Sites/peka/test.html:17\u000a"}"

Thanks!

/J

.get returning default

I think it would be useful to have .get take an optional param which is returned iff the requested key is missing (or has an undefined value).

Agree?

Support for sessionStorage?

Is there any interest from anyone else in support for sessionStorage as an alternative to localStorage?

There are times when I just want to keep the data for the browser session. Mostly logged-in user info for a client side app.

Wrapper through __defineGetter__ and __defineSetter__

Hello,

Could we improve store.js creating a wrapper through defineGetter and defineSetter for code like this?

store.user = {name:'Foo'}

// Open browser
alert(store.user.name); // Show's 'Foo'

I have tried with this:

store.__defineGetter__('user',function(){return this.get('user')});
store.__defineSetter__('user',function(val){return this.set('user',val)});

You could add these definitions in get and set functions.

What do you think?

Thanks!

Performance issue on Safari/iOS iPad 3

It seems the initialisation of the store is really slow on Safari/iOS

How to reproduce:

  • I create a basic page cached with appcache
  • onLoad I call store.get() and update a using innerHTML.

=> On Chrome, the page is "instant" I only see a little flicks
=> On iPad3 / Safari, I have to wait 4 seconds until the page is updated
=> Next get/set are fast

According to this article (http://hacks.mozilla.org/2012/03/there-is-no-simple-solution-for-local-storage/) local storage is slow but I didn't think so much ??

  • Is there best practices ?
  • Is there a tips on iOS ?
  • May be the first access of appcache slow down the process ?

IE10 Failing by HierarchyRequestError

I'm getting error "HierarchyRequestError" in Internet Explorer 10 on Windows 7.
Console shows that error occured on line 98.
The statement is shown below.


storageOwner.appendChild(storage)

Closing iframe with frame tag?

Is there a reason for closing iframe tag with frame on line 77 of store.js?
<iframe src="/favicon.ico"></frame>
This causes trouble in IE7 - it hangs while loading page.
Tried changing first tag to frame and it works, but I'm not sure if there was some reason for doing it with different tags?

test fails in IE7

the getAll function fails in IE7

test reports the error message

first pass bad assert: Tests should not throw: "{"message":"Object doesn't support this property or method","number":-2146827850,"description":"Object doesn't support this property or method"}"

I added some tracing to narrow it down and it gets to getAll call but in the getAll function the typeof storage.load is unknown

AMD implementation breaks sites

I finally found store.js while researching strange Javascript errors that I've encountered in my logs for some time now.

It seems like some quite popular Chrome plugin uses store.js, so it gets executed on my site even though I do not use store.js myself.

The problem is that store.js breaks my site! It confuses Dojo's AMD loader (and probably any other AMD loader too) when being loaded via a script tag in an AMD environment.

So when a page or browser plugin includes it via <script src="store.min.js"></script> when e.g. the Dojo Toolkit was loaded before, store.js will call define(store), but the AMD loader will be unable to find out where that define came from and cannot determine any module ID. It will then fall back to the last used module ID, which can break things quite heavily.

So define(store) should be changed to define('store', store) to provide an explicit module ID.

Type munge

Right now, this is false in Chrome:
store.set('x', 1) == store.get('x')
because Number 1, when stored, is coerced to a string. (Similarly, objects are coerced to "[object Object]".

How about testing for a JSON object and serializing with that?

exists(key) function

It would be useful to have a store.exists("somekey") function that returns true/false. Getter function can be used but it includes parsing.

Add hook for storage event

Would it be possible to add a way to hook into the HTML5 storage event with this library?

Demo of the functionality I'm looking for (but doesn't use store.js, obviously).

I'm thinking something like:

// All Windows / Tabs:
store.on('keyName', function(s){
    console.log(s.newValue);
});

// Window / Tab 1:
store.set('keyName', 'testValue');

// All other Windows / Tabs:
// 'testValue' is logged.

I'm implementing my own solution for this with the following code:

// All Windows / Tabs:
// Hook into the storage event
$(window).on('storage', function(e){
    // Keys we actually care about.
    var keys = ['timeStamp', 'key', 'oldValue', 'newValue', 'url'], newEvent = {};
    e = e.originalEvent; // jQuery puts the original event here
    for (var i in keys) {
        i = keys[i];
        if (i.substr(3) === 'Value') {
            // Get the value back just like we put it into store.set()
            newEvent[i] = store.deserialize(e[i]);
        } else {
            newEvent[i] = e[i];
        }
    }

    // Send the event to global listeners that want to know about all storage changes.
    newEvent.type = 'localStorage';
    $(document).trigger(newEvent);
    // Send the event to listeners for this key only.
    newEvent.type = newEvent.key + '.localStorage';
    $(document).trigger(newEvent);
});

$(document).on('keyName.localStorage', function(e){console.log(e.newValue);});

// Window / Tab 1:
store.set('keyName', 'testValue');

// All other Windows / Tabs:
// 'testValue' is logged.

This seems like the perfect addition to this library. It would make cross-window/tab communication with store.js dead-simple. Want all of your web app tabs to know you just got a new message in the current tab? Just call store.set('newMessage', 'hey!');.

Of course, it would only work when localStorage is supported, but it would be easy enough to indicate in the .on() function's return value whether or not listening is enabled.

I can submit a pull request if you're interested.

store.js and IE9

First, thanks for a great lib!

Maybe not an issue with store.js per se but is it correct that IE9 + store.js can't persist data between closing/starting browser?
localStorage["foo"] = "bar" in IE9 console isn't persisted if I close the browser either so I guess that's just how IE9 works.. which is kind of bad. Do you know anything more about this or maybe a possible way around it?

Using the set method on IE8 sometimes results in a crash (forced browser shutdown)

This is not easy to reproduce. I had your library working fine, and then at some point it started to crash on my every time I use the set method. It is clearly an IE issue and not an issue with your library because an FF-IE8-only-library that I was using before was also ocasinally the same behavior. I though people using local storage should be aware of a potential problem with IE.

IE 7 throws error if number, or string starting with number, is used as key

If you attempt to use a number, or a string starting with a number, as a key, then IE 7 will throw an error, e.g.

This name may not begin with the '1' character

I’m not sure if using numbers or strings starting with numbers as keys is meant to be supported, but it seems to work in IE 8 and other browsers.

Test page:

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">

    <script type="text/javascript" src="store.js"></script>

    <title>Test store.js</title>
</head>
<body>

<button onclick="store.set('string', 'value');"><code>store.set('string', 'value')</code></button>

<button onclick="store.set('123456', 'value');"><code>store.set('123456', 'value')</code></button>

<button onclick="store.set(123456, 'value');"><code>store.set(123456, 'value')</code></button>

<br>
<br>

<button onclick="alert(store.get('string', 'value'));"><code>store.get('string', 'value')</code></button>

<button onclick="alert(store.get('123456', 'value'));"><code>store.get('123456', 'value')</code></button>

<button onclick="alert(store.get(123456, 'value'));"><code>store.get(123456, 'value')</code></button>

</body>

</html>

I’ve worked around the issue by patching store.js to append 'string_' to the key within the get(), set() and remove() functions passed to withIEStorage(), but I’m not sure if this is optimal.

Error in line 49 in FF 3.6.13

Hi Marcus,

Line 49 in Store.js
49 if (localStorageName in win && win[localStorageName]) {

crashes with "Security error code: 1000" if the following option is set in About:Config

dom.storage.enabled : false

Specifically, it is the segment
win[localStorageName]
that causes this to barf.

So we need a more reliable way to test for this.

Update store.min.js and store+json2 files

I admit I'm tremendously stupid for using one of those minified files without checking wether they are uptodate, but please could you update them for all those other careless code monkeys?

git tag

where is tag v1.3.4 and v1.3.5?

please tag it.

Safari Private browsing mode appears to support localStorage, but doesn't

Apparently this is by design. When Safari (OS X or iOS) is in private browsing mode, it appears as though localStorage is available, but trying to call .setItem throws an exception.

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

What happens is that the window object still exposes localStorage in the global namespace, but when you call setItem, this exception is thrown. Any calls to .removeItem are ignored.

I believe the simplest fix (although I haven't tested this cross browser yet) would be to alter the function isLocalStorageNameSupported() to test that you can also set some value.

currently:

function isLocalStorageNameSupported() {
    try { return (localStorageName in win && win[localStorageName]) }
        catch(err) { return false }
}

proposed:

function isLocalStorageNameSupported() {
    try { 
        var supported = (localStorageName in win && win[localStorageName]);
        if (supported) { localStorage.setItem("storage", ""); localStorage.removeItem("storage");
        return supported;
    }
    catch(err) { return false }
}

Of course it's kind of silly to call this every time you want to check that storage is supported, so you could memoize it, but you get the idea.

store.get('randomKey') fails because JSON.parse('') raises syntax error

--- a/vendor/store.js
+++ b/vendor/store.js
@@ -44,7 +44,7 @@ var store = (function(){
                return JSON.stringify(value)
        }
        api.deserialize = function(value) {
-               if (typeof value != 'string') { return undefined }
+               if (typeof value != 'string' || !value) { return undefined }
                return JSON.parse(value)
        }

IE10 Failing

I'm getting error "Unable to get property 'appendChild' of undefined or null reference" in Internet Explorer 10 on Windows 8 ... seems to be an issue with the frame storage detection.

Feature Request: Object Watching

It'd be really awesome if we could completely drop the need for localStorage.getItem/setItem and store.get/set.

Looking at https://gist.github.com/384583, it looks like it'd be possible to bind an object directly to localStorage. In practice, you could simply associate a few objects with their localStorage keys and then have a field day; no need to worry about get/store ever again. All you'd need to know is that it's an object and it's always up to date.

In other words, this would be unfathomably awesome.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.