Ich suchte nach einer Möglichkeit, zwischen mehreren Registerkarten oder Fenstern in einem Browser (in derselben Domäne, nicht in CORS) zu kommunizieren, ohne Spuren zu hinterlassen. Es gab mehrere Lösungen:
Die erste ist wahrscheinlich die schlechteste Lösung - Sie müssen ein Fenster von Ihrem aktuellen Fenster aus öffnen und können dann nur kommunizieren, solange Sie die Fenster geöffnet halten. Wenn Sie die Seite in einem der Fenster neu laden, haben Sie höchstwahrscheinlich die Kommunikation verloren.
Der zweite Ansatz, der postMessage verwendet, ermöglicht wahrscheinlich die Kommunikation zwischen den Ursprüngen, hat jedoch das gleiche Problem wie der erste Ansatz. Sie müssen ein Fensterobjekt pflegen.
Drittens können Sie mithilfe von Cookies einige Daten im Browser speichern. Dies kann so aussehen, als würden Sie eine Nachricht an alle Fenster in derselben Domain senden. Das Problem ist jedoch, dass Sie nie wissen können, ob alle Registerkarten die "Nachricht" bereits gelesen haben oder nicht Aufräumen. Sie müssen eine Art Zeitüberschreitung implementieren, um das Cookie regelmäßig zu lesen. Darüber hinaus sind Sie durch die maximale Cookie-Länge von 4 KB begrenzt.
Die vierte Lösung, die localStorage verwendet, schien die Einschränkungen von Cookies zu überwinden, und sie kann sogar mithilfe von Ereignissen abgehört werden. Wie man es benutzt, ist in der akzeptierten Antwort beschrieben.
Edit 2018: Die akzeptierte Antwort funktioniert immer noch, aber es gibt eine neuere Lösung für moderne Browser, um BroadcastChannel zu verwenden. In der anderen Antwort finden Sie ein einfaches Beispiel für die einfache Übertragung von Nachrichten zwischen Registerkarten mithilfe von BroadcastChannel.
quelle
Antworten:
Edit 2018: Sie können BroadcastChannel besser für diesen Zweck verwenden, siehe andere Antworten unten. Wenn Sie dennoch Localstorage für die Kommunikation zwischen Registerkarten verwenden möchten, gehen Sie folgendermaßen vor:
Um benachrichtigt zu werden, wenn ein Tab eine Nachricht an andere Tabs sendet, müssen Sie lediglich das Speicherereignis binden. Gehen Sie auf allen Registerkarten folgendermaßen vor:
Die Funktion
message_receive
wird jedes Mal aufgerufen, wenn Sie einen Wert von localStorage auf einer anderen Registerkarte festlegen. Der Ereignis-Listener enthält auch die Daten, die neu auf localStorage festgelegt wurden, sodass Sie nicht einmal das localStorage-Objekt selbst analysieren müssen. Dies ist sehr praktisch, da Sie den Wert direkt nach dem Festlegen zurücksetzen können, um alle Spuren effektiv zu bereinigen. Hier sind Funktionen für Messaging:Sobald Ihre Registerkarten an das Ereignis onstorage gebunden sind und Sie diese beiden Funktionen implementiert haben, können Sie einfach eine Nachricht an andere Registerkarten senden, die beispielsweise Folgendes aufrufen:
Denken Sie daran, dass das zweimalige Senden derselben Nachricht nur einmal weitergegeben wird. Wenn Sie also Nachrichten wiederholen müssen, fügen Sie ihnen eine eindeutige Kennung hinzu, z
Denken Sie auch daran, dass die aktuelle Registerkarte, auf der die Nachricht gesendet wird, sie nicht tatsächlich empfängt, sondern nur andere Registerkarten oder Fenster in derselben Domäne.
Sie können fragen, was passiert, wenn der Benutzer eine andere Webseite lädt oder seinen Tab unmittelbar nach dem Aufruf von setItem () vor dem Aufruf von removeItem () schließt. Nach meinen eigenen Tests hält der Browser das Entladen in der Warteschleife, bis die gesamte Funktion abgeschlossen
message_broadcast()
ist. Ich habe getestet, ob es einen sehr langen for () -Zyklus gibt, und es hat immer noch darauf gewartet, dass der Zyklus beendet ist, bevor es geschlossen wird. Wenn der Benutzer die Registerkarte nur dazwischen beendet, hat der Browser nicht genügend Zeit, um die Nachricht auf der Festplatte zu speichern. Daher scheint mir dieser Ansatz eine sichere Methode zum Senden von Nachrichten ohne Spuren zu sein. Kommentare willkommen.quelle
Zu diesem Zweck gibt es eine moderne API - Broadcast Channel
Es ist so einfach wie:
Abgesehen von der API-Sauberkeit ist dies wahrscheinlich der Hauptvorteil dieser API - keine Objekt-Stringifizierung.
Derzeit unterstützt nur in Chrome und Firefox, aber Sie können einen polyfill finden , die localstorage verwendet.
quelle
Für diejenigen, die nach einer Lösung suchen, die nicht auf jQuery basiert, ist dies eine einfache JavaScript-Version der von Thomas M bereitgestellten Lösung:
quelle
Checkout AcrossTabs - Einfache Kommunikation zwischen originübergreifenden Browser-Registerkarten. Es verwendet eine Kombination aus postMessage und sessionStorage API, um die Kommunikation viel einfacher und zuverlässiger zu machen.
Es gibt verschiedene Ansätze und jeder hat seine eigenen Vor- und Nachteile. Lassen Sie uns jeweils diskutieren:
Lokaler Speicher
Vorteile :
Nachteile :
Kekse
Vorteile:
Nachteile:
Die Daten werden bei jeder HTTP-Anforderung (HTML, Bilder, JavaScript, CSS usw.) an den Server zurückgesendet, wodurch der Datenverkehr zwischen Client und Server erhöht wird.
In der Regel sind folgende zulässig:
sessionStorage
Vorteile:
localStorage
.Nachteile:
localStorage
arbeitet tt auf same-origin policy . Gespeicherte Daten können also nur am selben Ursprung verfügbar sein.POST-Meldung
Vorteile:
Nachteile:
targetOrigin
und eine Überprüfung der Richtigkeit der Daten, die an den Nachrichtenlistener weitergeleitet werden.Eine Kombination aus PostMessage + SessionStorage
Verwenden von postMessage zur Kommunikation zwischen mehreren Registerkarten und gleichzeitiges Verwenden von sessionStorage in allen neu geöffneten Registerkarten / Fenstern, um die Datenübergabe aufrechtzuerhalten. Die Daten bleiben erhalten, solange die Registerkarten / Fenster geöffnet bleiben. Selbst wenn die Registerkarte / das Fenster des Öffners geschlossen wird, enthalten die geöffneten Registerkarten / Fenster die gesamten Daten, auch nachdem sie aktualisiert wurden.
Ich habe hierfür eine JavaScript-Bibliothek mit dem Namen AcrossTabs geschrieben, die die postMessage-API verwendet, um zwischen originalübergreifenden Registerkarten / Fenstern und sessionStorage zu kommunizieren und die geöffnete Tabs / Windows-Identität so lange beizubehalten, wie sie aktiv sind.
quelle
AcrossTabs
es mit möglich, eine andere Website in einem anderen Tab zu öffnen und die Daten von diesem auf den übergeordneten Tab zu übertragen? Ich werde Authentifizierungsdetails für die andere Website haben.Eine andere Methode, die Menschen in Betracht ziehen sollten, ist Shared Workers. Ich weiß, dass es ein innovatives Konzept ist, aber Sie können ein Relay auf einem Shared Worker erstellen, das VIEL schneller als localstorage ist und keine Beziehung zwischen dem Eltern- / Kind-Fenster erfordert, solange Sie denselben Ursprung haben.
Siehe meine Antwort hier für eine Diskussion, die ich darüber gemacht habe.
quelle
Es gibt eine winzige Open-Source-Komponente zum Synchronisieren / Kommunizieren zwischen Registerkarten / Fenstern desselben Ursprungs (Haftungsausschluss - ich bin einer der Mitwirkenden!)
localStorage
.https://github.com/jitbit/TabUtils
PS Ich habe mir erlaubt, es hier zu empfehlen, da die meisten "Lock / Mutex / Sync" -Komponenten bei Websocket-Verbindungen ausfallen, wenn Ereignisse fast gleichzeitig auftreten
quelle
Ich habe eine Bibliothek sysend.js erstellt , sie ist sehr klein, Sie können den Quellcode überprüfen. Die Bibliothek hat keine externen Abhängigkeiten.
Sie können es für die Kommunikation zwischen Registerkarten / Fenstern in demselben Browser und derselben Domäne verwenden. Die Bibliothek verwendet BroadcastChannel (falls unterstützt) oder ein Speicherereignis von localStorage.
API ist sehr einfach:
Wenn Ihr Browser BroadcastChannel unterstützt, hat er ein Literalobjekt gesendet (aber es wird tatsächlich vom Browser automatisch serialisiert). Wenn nicht, wird es zuerst in JSON serialisiert und am anderen Ende deserialisiert.
Die aktuelle Version verfügt auch über eine Hilfs-API zum Erstellen eines Proxys für die domänenübergreifende Kommunikation. (Es erfordert eine einzelne HTML-Datei in der Zieldomäne).
Hier ist eine Demo .
EDIT :
Neue Version auch Unterstützung bei domänenübergreifender Kommunikation, wenn Sie spezielle umfassen
proxy.html
Datei auf Zieldomäne und Call -proxy
Funktion von Quelldomäne:(proxy.html ist eine sehr einfache HTML-Datei, die nur ein Skript-Tag mit der Bibliothek enthält).
Wenn Sie eine bidirektionale Kommunikation wünschen, müssen Sie dasselbe in der
target.com
Domäne tun .HINWEIS : Wenn Sie dieselbe Funktionalität mit localStorage implementieren, liegt ein Problem im IE vor. Das Speicherereignis wird an dasselbe Fenster gesendet, das das Ereignis ausgelöst hat, und für andere Browser wird es nur für andere Registerkarten / Fenster aufgerufen.
quelle
Ich habe ein Modul erstellt, das dem offiziellen Broadcast- Kanal entspricht, aber Fallbacks basierend auf localstorage, indexeddb und Unix-Sockets aufweist. Dies stellt sicher, dass es auch mit Webworkern oder NodeJS immer funktioniert. Siehe pubkey: BroadcastChannel
quelle
Ich habe einen Artikel dazu in meinem Blog geschrieben: http://www.ebenmonney.com/blog/how-to-implement-remember-me-functionality-using-token-based-authentication-and-localstorage-in-a- Webanwendung .
Mit einer von mir erstellten Bibliothek
storageManager
können Sie dies wie folgt erreichen:Es gibt auch andere bequeme Methoden, um auch andere Szenarien zu handhaben
quelle
Dies ist ein Entwicklungsteil
storage
der Antwort von Tomas M für Chrome. Wir müssen den Hörer hinzufügenDas Laden / Speichern eines Elements im Speicher führt dieses Ereignis nicht aus - wir MÜSSEN es manuell durch auslösen
und jetzt erhalten alle geöffneten Registerkarten ein Ereignis
quelle