utilizzare localStorage tra sottodomini


95

Sto sostituendo i cookie con localStorage sui browser che possono supportarlo (chiunque tranne IE). Il problema è site.com e www . site.com memorizza i propri oggetti localStorage separati. Credo che www sia considerato un sottodominio (una decisione stupida se me lo chiedi). Se un utente era originariamente su site.com e decide di digitare www . site.com alla sua prossima visita, tutti i suoi dati personali saranno inaccessibili. Come faccio a fare in modo che tutti i miei "sottodomini" condividano lo stesso localStorage del dominio principale?


4
Firefox e IE8 supportano l'archiviazione dei dati persistenti in un dominio specificato dall'utente. Ad esempio su FF, puoi fare globalStorage ['site.com'] e questo sarà accessibile a www.site.com e site.com. Non ho ancora capito come farlo nell'implementazione di Chrome.
JoJo

9
Considera di utilizzare uno o il secondo: reindirizza tutti gli utenti che visitano con www. sottodominio al dominio senza sottodominio o viceversa.
Elad Nava

Ho creato un articolo molto tempo fa: Cross-Domain LocalStorage
jcubic

Risposte:


94

È così che lo uso nei domini ...

  • Usa un iframe dal tuo dominio principale, ad esempio parent.com
  • Quindi, su ogni dominio child.com, invia semplicemente un postMessage al tuo iframe parent.com
  • Tutto quello che devi fare è impostare un protocollo su come interpretare i tuoi messaggi postMessage per parlare con l'iframe di parent.com.

Spero possa essere d'aiuto :)


2
Questa è la vera risposta, non quella spuntata. L'ho fatto da solo, ma ho anche creato un comodo wrapper di callback con postMessage.
Jason Sebring

4
Ecco un buon articolo con un codice di esempio che spiega questo metodo: jcubic.wordpress.com/2014/06/20/cross-domain-localstorage
Todd Price

4
Tieni presente che ciò è possibile solo quando i cookie di terze parti non sono disabilitati: stackoverflow.com/a/44097269/4311428
Max

6
Apple ha aggiornato le impostazioni predefinite su Safari 7+ sia su desktop che su dispositivo mobile per bloccare i dati di terze parti. L'opzione è ora chiamata "Blocca cookie e altri dati di siti Web" che si riferisce a cose come localstorage che ora sono completamente isolate dal dominio. Questo metodo non funzionerà in Safari
Aranganathan

2
@Max @Aranganathan ancora funziona per caso domanda iniziale - site.com/ www.site.comfinché sottodomini sono sullo stesso dominio padre
Kostiantyn

41

Se stai utilizzando la soluzione iframe e postMessage solo per questo particolare problema, penso che potrebbe essere meno faticoso (sia dal punto di vista del codice che del calcolo) archiviare i dati in un cookie senza sottodominio e, se non lo è già in localStorage al caricamento, prendilo dal cookie .

Professionisti:

  • Non necessita dell'iframe aggiuntivo e della configurazione di postMessage.

Contro:

  • Renderà i dati disponibili su tutti i sottodomini (non solo su www), quindi se non ti fidi di tutti i sottodomini potrebbe non funzionare per te.
  • Invierà i dati al server ad ogni richiesta. Non eccezionale, ma a seconda del tuo scenario, forse ancora meno lavoro rispetto alla soluzione iframe / postMessage.
  • Se lo fai, perché non utilizzare direttamente i cookie? Dipende dal tuo contesto.
  • Dimensione massima del cookie 4K, totale in tutti i cookie per il dominio (grazie a Blake per averlo indicato nei commenti)

Sono d'accordo con altri commentatori, tuttavia, sembra che dovrebbe essere un'opzione specificabile per localStorage, quindi non sono necessarie soluzioni.


29
Contro: dimensione massima del cookie 4k
Blake Miller

17
Inoltre, come ho imparato a mie spese, il limite di 4k è per la somma delle dimensioni di tutti i cookie per un singolo dominio, non per ogni cookie.
Blake Miller

altri svantaggi: - i cookie saranno molto probabilmente bloccati dagli adblocker - i cookie sono destinati a essere utilizzati per condividere piccoli dati tra server e client, se il server non utilizza i dati memorizzati nel cookie, questo è di conseguenza un uso improprio
Enno

32

Suggerisco di reindirizzare site.com a www.site.com sia per coerenza che per evitare problemi come questo.

Inoltre, considera l'utilizzo di una soluzione cross-browser come PersistJS che può utilizzare ogni memoria nativa del browser.


Non ho accesso amministrativo ai server per eseguire un tale reindirizzamento. Quella libreria mi consente di condividere dati persistenti tra www e non www? Dopo aver letto un po ', sembra che quasi tutti i meccanismi di archiviazione dei browser non lo consentano. Non importa se si tratta di cookie o localStorage, ci imbatteremo in questo problema ...
JoJo

Sì, l'archiviazione dipende normalmente dal dominio, incluso il sottodominio. Questo è il motivo per cui ho suggerito un reindirizzamento. Non hai necessariamente bisogno dell'accesso come amministratore, usa semplicemente una regola .htaccess nella radice del documento
Eran Galperin

1
@JoJo Ci sono diversi modi per reindirizzare, ad esempio inviando l'intestazione Location, o tramite il <meta>tag HTML, o anche JS tramite window.location.
Sony Santos

1
Questo è solo evitare la risposta. Vedi la risposta di Mayank corretta.
Jason Sebring

1
+1 @avoiding, inoltre questo è irrilevante per altri casi, come quello per cui sono qui lang1.domain.com - lang2.domain.com
r --------- k

6

Imposta su cookie nel dominio principale -

document.cookie = "key=value;domain=.mydomain.com"

e quindi prendere i dati da qualsiasi dominio principale o sottodominio e impostarli su localStorage




1

Questo è come:

Per la condivisione tra i sottodomini di un determinato superdominio (ad esempio example.com), esiste una tecnica che puoi utilizzare in quella situazione. Esso può essere applicato a localStorage, IndexedDB, SharedWorker, BroadcastChannel, ecc, tutti che offrono funzionalità condivise tra le pagine dello stesso di origine, ma per qualche motivo non rispetta alcuna modificadocument.domain che avrebbe permesso loro di utilizzare l'superdominio loro origine direttamente.

(1) Scegli un dominio "principale" a cui appartengono i dati: ad esempio, https://example.com o https://www.example.com manterranno i tuoi dati localStorage. Supponiamo che tu scelga https://example.com .

(2) Usa localStorage normalmente per le pagine di quel dominio scelto.

(3) In tutte le pagine https://www.example.com (l' altro dominio), utilizzare javascript per impostare document.domain = "example.com";. Quindi crea anche un nascosto <iframe>e navigalo in una pagina sul dominio https://example.com scelto ( non importa quale , purché tu possa inserire un piccolo frammento di javascript lì. Se tu " stai creando il sito, crea una pagina vuota appositamente per questo scopo. Se stai scrivendo un'estensione o uno script utente in stile Greasemonkey e quindi non hai alcun controllo sulle pagine su example.com server della pagina , scegli la pagina più leggera che puoi trovare e inserisci il tuo script in essa. Alcuni tipo di pagina "non trovata" probabilmente andrebbe bene).

(4) Lo script sulla pagina iframe nascosto deve solo (a) essere impostato document.domain = "example.com";e (b) notificare alla finestra genitore quando ciò è fatto. Dopodiché, la finestra genitore può accedere alla finestra iframe e a tutti i suoi oggetti senza restrizioni! Quindi la pagina iframe minimo è qualcosa del tipo:

<!doctype html>
<html>
<head>
  <script>
    document.domain = "example.com";
    window.parent.iframeReady();  // function defined & called on parent window
  </script>
</head>
<body></body>
</html>

Se scrivi uno script utente, potresti non voler aggiungere funzioni accessibili esternamente come iframeReady()al tuo unsafeWindow, quindi invece un modo migliore per notificare lo script utente della finestra principale potrebbe essere quello di utilizzare un evento personalizzato:

    window.parent.dispatchEvent(new CustomEvent("iframeReady"));

Che rileveresti aggiungendo un listener per l'evento "iframeReady" personalizzato alla finestra della tua pagina principale.

(NOTA: devi impostare document.domain = "esempio.com" anche se il dominio dell'iframe è già esempio.com : l'assegnazione di un valore a document.domain imposta implicitamente la porta di origine su null ed entrambe le porte devono corrispondere per l'iframe e il suo genitore devono essere considerati della stessa origine. Vedere la nota qui: https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#Changing_origin )

(5) Una volta che il nascosti iframe ha informato la sua finestra di padre che è pronto, lo script nella finestra genitore può semplicemente utilizzare iframe.contentWindow.localStorage, iframe.contentWindow.indexedDB, iframe.contentWindow.BroadcastChannel, iframe.contentWindow.SharedWorkerinvece di window.localStorage, window.indexedDBecc ... e tutti questi oggetti saranno scope alla scelta https: // example.com origin, quindi avranno la stessa origine condivisa per tutte le tue pagine!

La parte più imbarazzante di questa tecnica è che devi attendere il caricamento dell'iframe prima di procedere. Quindi non puoi semplicemente iniziare a usare allegramente localStorage nel tuo gestore DOMContentLoaded, per esempio. Inoltre potresti voler aggiungere un po 'di gestione degli errori per rilevare se l'iframe nascosto non riesce a caricarsi correttamente.

Ovviamente, dovresti anche assicurarti che l'iframe nascosto non venga rimosso o navigato durante la vita della tua pagina ... OTOH Non so quale sarebbe il risultato, ma molto probabilmente potrebbero accadere cose brutte.

E un avvertimento: l'impostazione / modifica document.domainpuò essere bloccata utilizzando l' Feature-Policyintestazione, nel qual caso questa tecnica non sarà utilizzabile come descritto.


Tuttavia, c'è una generalizzazione significativamente più complicata di questa tecnica, che non può essere bloccata da Feature-Policy, e che consente anche a domini completamente non correlati di condividere dati, comunicazioni e lavoratori condivisi (cioè non solo sottodomini di un comune superdominio). @Mayank Jain lo ha già descritto nella loro risposta, ovvero:

L'idea generale è che, proprio come sopra, crei un iframe nascosto per fornire l'origine corretta per l'accesso; ma invece di afferrare direttamente le proprietà della finestra dell'iframe, usi lo script all'interno dell'iframe per fare tutto il lavoro e comunichi tra l'iframe e la tua finestra principale usando solo postMessage()e addEventListener("message",...).

Funziona perché postMessage()può essere utilizzato anche tra finestre di origine diversa. Ma è anche molto più complicato perché devi passare tutto attraverso una sorta di infrastruttura di messaggistica che crei tra l'iframe e la finestra principale, piuttosto che usare solo le API localStorage, IndexedDB, ecc. Direttamente nel codice della tua finestra principale.


0

Ecco come l'ho risolto per il mio sito web. Ho reindirizzato tutte le pagine senza www a www.site.com. In questo modo, ci vorrà sempre localstorage di www.site.com

Aggiungi quanto segue al tuo .htacess , (creane uno se non lo hai già) nella directory principale

RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

5
Sono molto tentato di sottovalutare questo, ma non lo farò perché può aiutare il caso d'uso dell'OP, ma per le persone che vogliono mantenere le sessioni su myapp.com e developers.myapp.com e support.myapp.com, questa risposta è non bene.
Don Omondi

hey @DonOmondi Apprezzerei se mi aiutassi con i link per quello che suggerisci!
Ayush Baheti

3
L'OP ha chiesto "usa localStorage tra sottodomini" la tua risposta è "reindirizza www a non-www" cose molto diverse ma può funzionare se e solo se il sottodominio specifico è "www.abc.com" per casi generali alcune altre risposte qui sono più pratico.
Don Omondi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.