Je cherchais un moyen de communiquer entre plusieurs onglets ou fenêtres dans un navigateur (sur le même domaine, pas CORS) sans laisser de traces. Il y avait plusieurs solutions:
La première est probablement la pire solution - vous devez ouvrir une fenêtre à partir de votre fenêtre actuelle et vous ne pouvez communiquer que tant que vous gardez les fenêtres ouvertes. Si vous rechargez la page dans l'une des fenêtres, vous avez probablement perdu la communication.
La deuxième approche, utilisant postMessage, permet probablement une communication inter-origine, mais souffre du même problème que la première approche. Vous devez gérer un objet fenêtre.
Troisièmement, à l'aide de cookies, stockez certaines données dans le navigateur, ce qui peut effectivement ressembler à l'envoi d'un message à toutes les fenêtres du même domaine, mais le problème est que vous ne pouvez jamais savoir si tous les onglets lisent déjà ou non le "message". nettoyer. Vous devez mettre en œuvre une sorte de délai d'expiration pour lire le cookie périodiquement. De plus, vous êtes limité par la longueur maximale des cookies, qui est de 4 Ko.
La quatrième solution, utilisant localStorage, semble surmonter les limitations des cookies, et peut même être écoutée en utilisant des événements. Comment l'utiliser est décrit dans la réponse acceptée.
Edit 2018: la réponse acceptée fonctionne toujours, mais il existe une solution plus récente pour les navigateurs modernes, pour utiliser BroadcastChannel. Voir l'autre réponse pour un exemple simple décrivant comment transmettre facilement un message entre les onglets à l'aide de BroadcastChannel.
la source
Réponses:
Edit 2018: Vous pouvez mieux utiliser BroadcastChannel à cette fin, voir les autres réponses ci-dessous. Pourtant, si vous préférez toujours utiliser localstorage pour la communication entre les onglets, procédez comme suit:
Pour être averti lorsqu'un onglet envoie un message à d'autres onglets, il vous suffit de lier l'événement «stockage». Dans tous les onglets, procédez comme suit:
La fonction
message_receive
sera appelée chaque fois que vous définissez une valeur de localStorage dans un autre onglet. L'écouteur d'événements contient également les données nouvellement définies sur localStorage, vous n'avez donc même pas besoin d'analyser l'objet localStorage lui-même. C'est très pratique car vous pouvez réinitialiser la valeur juste après sa définition, pour nettoyer efficacement les traces. Voici les fonctions de messagerie:Alors maintenant, une fois que vos onglets se lient à l'événement onstorage, et que ces deux fonctions sont implémentées, vous pouvez simplement diffuser un message vers d'autres onglets appelant, par exemple:
N'oubliez pas que l'envoi du même message deux fois ne sera propagé qu'une seule fois, donc si vous devez répéter des messages, ajoutez-leur un identifiant unique, comme
Rappelez-vous également que l'onglet actuel qui diffuse le message ne le reçoit pas réellement, uniquement d'autres onglets ou fenêtres du même domaine.
Vous pouvez demander ce qui se passe si l'utilisateur charge une page Web différente ou ferme son onglet juste après l'appel setItem () avant le removeItem (). Eh bien, d'après mes propres tests, le navigateur met le déchargement en attente jusqu'à ce que toute la fonction
message_broadcast()
soit terminée. J'ai testé pour y mettre un cycle très long pour () et il a encore attendu que le cycle se termine avant de fermer. Si l'utilisateur tue l'onglet juste entre les deux, alors le navigateur n'aura pas assez de temps pour enregistrer le message sur le disque, donc cette approche me semble être un moyen sûr d'envoyer des messages sans aucune trace. Commentaires bienvenus.la source
Il existe une API moderne dédiée à cet effet - Broadcast Channel
C'est aussi simple que:
Probablement, mis à part la propreté de l'API, c'est le principal avantage de cette API - aucune stringification d'objet.
Actuellement pris en charge uniquement dans Chrome et Firefox, mais vous pouvez trouver un polyfill qui utilise localStorage.
la source
Pour ceux qui recherchent une solution non basée sur jQuery, il s'agit d'une version JavaScript simple de la solution fournie par Thomas M:
la source
Checkout AcrossTabs - Communication facile entre les onglets du navigateur cross-origin. Il utilise une combinaison d' API postMessage et sessionStorage pour rendre la communication beaucoup plus facile et fiable.
Il existe différentes approches et chacune a ses propres avantages et inconvénients. Permet de discuter de chacun:
Stockage local
Avantages :
Inconvénients :
Biscuits
Avantages:
Les inconvénients:
Les données sont renvoyées au serveur pour chaque requête HTTP (HTML, images, JavaScript, CSS, etc.) - augmentant la quantité de trafic entre le client et le serveur.
En règle générale, les éléments suivants sont autorisés:
sessionStorage
Avantages:
localStorage
.Les inconvénients:
localStorage
, tt fonctionne sur la politique de même origine . Ainsi, les données stockées ne pourront être disponibles que sur la même origine.PostMessage
Avantages:
Les inconvénients:
targetOrigin
vérification et une vérification de l'intégritédes données transmises à l'écouteur de messages.Une combinaison de PostMessage + SessionStorage
Utilisation de postMessage pour communiquer entre plusieurs onglets et en même temps utilisation de sessionStorage dans tous les onglets / fenêtres nouvellement ouverts pour conserver les données transmises. Les données seront conservées tant que les onglets / fenêtres resteront ouverts. Ainsi, même si l'onglet / la fenêtre d'ouverture se ferme, les onglets / fenêtres ouverts auront toutes les données même après avoir été actualisés.
J'ai écrit une bibliothèque JavaScript pour cela, nommée AcrossTabs qui utilise l'API postMessage pour communiquer entre les onglets / fenêtres d'origine croisée et sessionStorage pour conserver l'identité des onglets / fenêtres ouverts aussi longtemps qu'ils vivent.
la source
AcrossTabs
, est-il possible d'ouvrir un site Web différent dans un autre onglet et d'en récupérer les données dans l'onglet parent? J'aurai les détails d'authentification pour un autre site Web.Les travailleurs partagés sont une autre méthode que les gens devraient envisager d'utiliser. Je sais que c'est un concept de pointe, mais vous pouvez créer un relais sur un Shared Worker qui est BEAUCOUP plus rapide que le stockage local et qui ne nécessite pas de relation entre la fenêtre parent / enfant, tant que vous êtes sur la même origine.
Voir ma réponse ici pour une discussion que j'ai faite à ce sujet.
la source
Il existe un petit composant open-source pour synchroniser / communiquer entre les onglets / fenêtres de la même origine (avertissement - je suis l'un des contributeurs!) Basé sur
localStorage
.https://github.com/jitbit/TabUtils
PS J'ai pris la liberté de le recommander ici car la plupart des composants "lock / mutex / sync" échouent sur les connexions websocket lorsque les événements se produisent presque simultanément
la source
J'ai créé une bibliothèque sysend.js , elle est très petite, vous pouvez vérifier son code source. La bibliothèque n'a pas de dépendances externes.
Vous pouvez l'utiliser pour la communication entre les onglets / fenêtres dans le même navigateur et domaine. La bibliothèque utilise BroadcastChannel, s'il est pris en charge, ou un événement de stockage de localStorage.
L'API est très simple:
lorsque votre navigateur prend en charge BroadcastChannel, il a envoyé un objet littéral (mais il est en fait auto-sérialisé par le navigateur) et sinon il est d'abord sérialisé en JSON et désérialisé à l'autre extrémité.
La version récente a également une API d'assistance pour créer un proxy pour la communication entre domaines. (il nécessite un seul fichier html sur le domaine cible).
Voici la démo .
MODIFIER :
La nouvelle version prend également en charge la communication entre domaines , si vous incluez un
proxy.html
fichier spécial sur le domaine cible et appelez laproxy
fonction à partir du domaine source:(proxy.html c'est un fichier html très simple, qui n'a qu'une seule balise de script avec la bibliothèque).
Si vous souhaitez une communication bidirectionnelle, vous devez faire de même sur le
target.com
domaine.REMARQUE : si vous implémentez la même fonctionnalité à l'aide de localStorage, il y a un problème dans IE. L'événement de stockage est envoyé à la même fenêtre, qui a déclenché l'événement et pour les autres navigateurs, il n'est appelé que pour les autres onglets / fenêtres.
la source
J'ai créé un module qui fonctionne de la même manière que le canal de diffusion officiel mais qui a des solutions de secours basées sur localstorage, indexeddb et unix-sockets. Cela garantit qu'il fonctionne toujours même avec les Webworkers ou NodeJS. Voir pubkey: BroadcastChannel
la source
J'ai écrit un article à ce sujet sur mon blog: http://www.ebenmonney.com/blog/how-to-implement-remember-me-functionality-using-token-based-authentication-and-localstorage-in-a- application Web .
En utilisant une bibliothèque que j'ai créée,
storageManager
vous pouvez y parvenir comme suit:Il existe également d'autres méthodes pratiques pour gérer d'autres scénarios
la source
Ceci est une
storage
partie du développement de Tomas M answer for Chrome. Il faut ajouter un auditeurCharger / enregistrer l'élément dans le stockage ne lance pas cet événement - nous DEVONS le déclencher manuellement en
et maintenant, tous les onglets ouverts recevront l'événement
la source