Подтвердить что ты не робот

Есть ли способ обхода использования html5 localstorage как на http, так и на https?

Мне нужно сохранить некоторую клиентскую часть данных, и эти данные слишком велики, чтобы сохранить их в файле cookie. LocalStorage казался идеальным способом сделать это, но дело в том, что на веб-сайте, который я буду использовать, есть некоторые части, которые работают на https и другие с помощью только http, а локальное хранилище не может получить доступ к данным из https, которые вы установили с помощью http это больше не похоже на жизнеспособное решение.

Любая идея, если есть какое-либо решение? Любые другие альтернативы?

4b9b3361

Ответ 1

Храните все данные в одном домене, например. https://my.domain.org/.

  • В протоколах https просто используйте localStorage.setItem('key', 'value') для сохранения данных.
  • В протоколах http вставьте кадр https и используйте postMessage для сохранения данных:

Демо: http://jsfiddle.net/gK7ce/4/ (страница-помощник находится в 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);

На странице http (s) фрейм может быть встроен следующим образом (заменить https://my.mydomain.com на фактический URL). Обратите внимание, что вы можете просто получить ссылку на фрейм и использовать src):

<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');

Обратите внимание, что метод является асинхронным, из-за postMessage. Реализация метода getItem должна выполняться по-разному:

var callbacks = {};
window.addEventListener('message', function(event) {
    if (event.source === frames['myPostMessage']) {
        var data = /^#localStorage#(\d+)(null)?#([\S\s]*)/.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);
});

Обратите внимание, что каждый обратный вызов сохраняется в хеше. Каждое сообщение также содержит идентификатор, так что окно, которое получает сообщение, вызывает соответствующий соответствующий обратный вызов.

Для полноты здесь метод LSremoveItem:

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