2012-05-08 11 views
12

Ho bisogno di memorizzare alcuni dati lato client e questi dati sono troppo grandi per memorizzarli in un cookie. LocalStorage mi è sembrato il modo perfetto per farlo, ma la cosa è che il sito web che userò questo ha alcune parti che funzionano su https e altre con solo http e come storage locale non può accedere ai dati da https che hai impostato con http questa non sembra più una soluzione valida.Esiste una soluzione alternativa per utilizzare html5 localstorage su http e https?

Qualche idea se esiste una soluzione a questo? Qualche altra alternativa?

+0

correlati (1) [stesso localStorage per HTTP e HTTPS?] (Http://stackoverflow.com/questions/5144471/same-localstorage-for- http-and-https), (2) [I database HTML5 e localStorage possono essere condivisi tra sottodomini?] (http://stackoverflow.com/questions/4177803/can-html5-databases-and-localstorage-be-shared-across -subdomains). –

risposta

21

Archiviare tutti i dati su un dominio, ad es. https://my.domain.org/.

  • Su https protocolli, è sufficiente utilizzare localStorage.setItem('key', 'value') per salvare i dati.
  • Su http protocolli, incorporare una cornice https, e utilizzare postMessage per salvare i dati:

Demo: http://jsfiddle.net/gK7ce/4/ (con la pagina di supporto essendo situato a 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); 

Nella pagina http (s), il telaio può essere incorporato come segue (sostituire https://my.mydomain.com con l'URL effettivo. Si noti che è possibile ottenere semplicemente un riferimento al telaio, e utilizzare l'attributo 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'); 

noti che il metodo è asincrona, a causa di postMessage. Un'implementazione del metodo getItem deve essere attuata in modo diverso:

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

Notare che ogni richiamata è memorizzato in un hash. Ogni messaggio contiene anche un identificativo, in modo che la finestra che riceve il messaggio chiami la richiamata corrispondente corretta.

Per completezza, ecco il metodo LSremoveItem:

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

Ho provato questo, ma quando l'iframe https prova a postare Messaggistica indietro alla finestra genitore http ricevo un errore "Tentativo JavaScript non sicuro di accedere al frame con l'URL ... Domini, protocolli e porte devono corrispondere". Qualche idea? – daniels

+1

Qualsiasi [SSCCE] (http://sscce.org/)? –

+0

Sto usando questo: https://github.com/mozilla/jschannel e questo esempio https://github.com/mozilla/jschannel/tree/master/example – daniels

Problemi correlati