Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
261 views
in Technique[技术] by (71.8m points)

html - Is there any workaround to make use of html5 localstorage on both http and https?

I need to store some data client side and this data is too large to store it in a cookie. LocalStorage seemed like the perfect way of doing this but the thing is that the website that i will be using this has some parts that work on https and others with just http and as local storage can't access data from https that you set with http this doesn't seem like a viable solution anymore.

Any idea if there is any solution to this? Any other alternatives?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Store all data on one domain, e.g. https://my.domain.org/.

  • On https protocols, simply use localStorage.setItem('key', 'value') to save the data.
  • On http protocols, embed a https frame, and use postMessage to save the data:

Demo: http://jsfiddle.net/gK7ce/4/ (with the helper page being located at http://jsfiddle.net/gK7ce/3/).

// Script at https://my.domain.org/postMessage
window.addEventListener('message', function(event) {
    // Domain restriction (to not leak variables to any page..)
    if (event.origin == 'http://my.domain.org' ||
        event.origin == 'https://my.domain.org') {
        var data = JSON.parse(event.data);
        if ('setItem' in data) {
            localStorage.setItem(data.setItem, data.value);
        } else if ('getItem' in data) {
            var gotItem = localStorage.getItem(data.getItem);
            // See below
            event.source.postMessage(
                '#localStorage#' + data.identifier + 
                (gotItem === null ? 'null#' : '#' + gotItem),
                event.origin
            );
        } else if ('removeItem' in data) {
            localStorage.removeItem(data.removeItem);
        }
    }
}, false);

On the http(s) page, the frame can be embedded as follows (replace https://my.mydomain.com with the actual URL. Note that you can simply get a reference to the frame, and use the src attribute):

<iframe name="myPostMessage" src="https://my.domain.org/postMessage" style="display:none;"></iframe>
// Example: Set the data
function LSsetItem(key, value) {
    var obj = {
        setItem: key,
        value: value
    };
    frames['myPostMessage'].postMessage(JSON.stringify(obj), 'https://my.domain.com');
}
LSsetItem('key', 'value');

Note that the method is asynchronous, because of postMessage. An implementation of the getItem method has to be implemented differently:

var callbacks = {};
window.addEventListener('message', function(event) {
    if (event.source === frames['myPostMessage']) {
        var data = /^#localStorage#(d+)(null)?#([Ss]*)/.exec(event.data);
        if (data) {
            if (callbacks[data[1]]) {
                // null and "null" are distinguished by our pattern
                callbacks[data[1]](data[2] === 'null' ? null : data[3]);
            }
            delete callbacks[data[1]];
        }
    }
}, false);
function LSgetItem(key, callback) {
    var identifier = new Date().getTime();
    var obj = {
        identifier: identifier,
        getItem: key
    };
    callbacks[identifier] = callback;
    frames['myPostMessage'].postMessage(JSON.stringify(obj), 'https://my.domain.com');
}
// Usage:
LSgetItem('key', function(value) {
    console.log('Value: ' + value);
});

Note that each callback is stored in a hash. Each message also contains an identifier, so that the window which receives the message calls the correct corresponding callback.

For completeness, here's the LSremoveItem method:

function LSremoveItem(key) {
    var obj = {
        removeItem:?key
    };
    frames['myPostMessage'].postMessage(JSON.stringify(obj), 'https://my.domain.com');
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...