Necesito almacenar algunos datos del lado del cliente y este tipo de datos es demasiado grande para almacenar en una cookie. LocalStorage parecía la manera perfecta de hacer esto, pero la cosa es que el sitio web que va a utilizar esto tiene algunas partes que trabajan en https y otros solo con http y como almacenamiento local no puede acceder a los datos de https que se establece con http esto no parece una solución viable ya.

Alguna idea de si hay alguna solución a esto? Otras alternativas?

OriginalEl autor daniels | 2012-05-08

1 Comentario

  1. 21

    Almacenar todos los datos en un dominio, por ejemplo,https://my.domain.org/.

    • En https protocolos, simplemente uso localStorage.setItem('key', 'value') para guardar los datos.
    • En http protocolos, incrustar un https marco, y el uso postMessage para guardar los datos:

    Demo: http://jsfiddle.net/gK7ce/4/ (con la ayuda de la página se encuentra en 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);

    Sobre http(s) de página, el marco puede estar integrado de la siguiente manera (reemplazar https://my.mydomain.com con la URL real. Tenga en cuenta que usted puede conseguir simplemente una referencia a la estructura, y el uso de la src atributo):

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

    Tenga en cuenta que el método es asincrónico, porque de postMessage. Una implementación de la getItem método debe ser aplicado de manera diferente:

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

    Tenga en cuenta que cada devolución de llamada que se almacena en un hash. Cada mensaje también contiene un identificador, por lo que la ventana que recibe el mensaje llama la correcta devolución de llamada.

    Para la integridad, aquí está el LSremoveItem método:

    function LSremoveItem(key) {
        var obj = {
            removeItem: key
        };
        frames['myPostMessage'].postMessage(JSON.stringify(obj), 'https://my.domain.com');
    }
    He probado esto, pero cuando el https iframe intenta postMessage a http ventana principal me sale un error «no seguro JavaScript intento de acceso a marco con la dirección URL… Dominios, protocolos y puertos deben coincidir.» Alguna idea?
    Cualquier SSCCE?
    Estoy usando esto: github.com/mozilla/jschannel y este ejemplo github.com/mozilla/jschannel/tree/master/example
    Esta es una solución inteligente, pero dejó de funcionar en iOS 7/Safari. Alguien más tiene problemas con esto ahora? El almacenamiento local parece ser el uso de la ventana principal del protocolo en lugar del iframe. Alguien tiene una nueva respuesta a contribuir?
    El problema con Safari es causada por la «bloquear cookies y otros datos del sitio web» preferencia. Cuando se establece en «De terceros y anunciantes», localStorage no es compartida. Se debe establecer en «Nunca», como se ve en la siguiente imagen: i.stack.imgur.com/AP4ed.png.

    OriginalEl autor Rob W

Dejar respuesta

Please enter your comment!
Please enter your name here