Estaba buscando una manera de comunicarme entre múltiples pestañas o ventanas en un navegador (en el mismo dominio, no CORS) sin dejar rastros. Hubo varias soluciones:
La primera es probablemente la peor solución: debe abrir una ventana desde su ventana actual y luego puede comunicarse solo mientras mantenga las ventanas abiertas. Si vuelve a cargar la página en cualquiera de las ventanas, lo más probable es que haya perdido la comunicación.
El segundo enfoque, usando postMessage, probablemente habilita la comunicación de origen cruzado, pero sufre el mismo problema que el primer enfoque. Necesita mantener un objeto de ventana.
La tercera forma, usando cookies, almacena algunos datos en el navegador, lo que efectivamente puede parecer enviar un mensaje a todas las ventanas en el mismo dominio, pero el problema es que nunca se puede saber si todas las pestañas leen el "mensaje" ya o no antes limpiar. Debe implementar algún tipo de tiempo de espera para leer la cookie periódicamente. Además, está limitado por la longitud máxima de la cookie, que es 4KB.
La cuarta solución, usando localStorage, parecía superar las limitaciones de las cookies, e incluso se puede escuchar usando eventos. Cómo usarlo se describe en la respuesta aceptada.
Editar 2018: la respuesta aceptada aún funciona, pero hay una solución más nueva para los navegadores modernos, usar BroadcastChannel. Consulte la otra respuesta para ver un ejemplo simple que describe cómo transmitir fácilmente mensajes entre pestañas utilizando BroadcastChannel.
fuente
Respuestas:
Editar 2018: es mejor que use BroadcastChannel para este propósito, vea otras respuestas a continuación. Sin embargo, si aún prefiere utilizar el almacenamiento local para la comunicación entre pestañas, hágalo de esta manera:
Para recibir una notificación cuando una pestaña envía un mensaje a otras pestañas, simplemente necesita vincular el evento 'almacenamiento'. En todas las pestañas, haz esto:
Se
message_receive
llamará a la función cada vez que establezca cualquier valor de localStorage en cualquier otra pestaña. El detector de eventos también contiene los datos recién configurados en localStorage, por lo que ni siquiera necesita analizar el objeto localStorage en sí. Esto es muy útil porque puede restablecer el valor justo después de que se configuró, para limpiar eficazmente cualquier rastro. Aquí hay funciones para la mensajería:Entonces, una vez que sus pestañas se unen al evento de almacenamiento y que tiene implementadas estas dos funciones, simplemente puede transmitir un mensaje a otras pestañas llamando, por ejemplo:
Recuerde que enviar exactamente el mismo mensaje dos veces se propagará solo una vez, por lo que si necesita repetir mensajes, agrégueles un identificador único, como
Recuerde también que la pestaña actual que transmite el mensaje en realidad no lo recibe, solo otras pestañas o ventanas en el mismo dominio.
Puede preguntar qué sucede si el usuario carga una página web diferente o cierra su pestaña justo después de la llamada setItem () antes de removeItem (). Bueno, según mis propias pruebas, el navegador pone la descarga en espera hasta que la función completa
message_broadcast()
haya finalizado. Probé para poner dentro un ciclo muy largo para () y todavía esperó a que el ciclo terminara antes de cerrar. Si el usuario mata la pestaña justo en el medio, entonces el navegador no tendrá tiempo suficiente para guardar el mensaje en el disco, por lo que este enfoque me parece una forma segura de cómo enviar mensajes sin ningún rastro. Comentarios bienvenidosfuente
Hay una API moderna dedicada para este propósito: Broadcast Channel
Es tan fácil como:
Probablemente, aparte de la limpieza de la API, es el principal beneficio de esta API: no hay cadena de objetos.
Actualmente solo se admite en Chrome y Firefox, pero puede encontrar un polyfill que use localStorage.
fuente
Para aquellos que buscan una solución no basada en jQuery, esta es una versión simple de JavaScript de la solución provista por Thomas M:
fuente
Checkout AcrossTabs : comunicación fácil entre pestañas de navegador de origen cruzado. Utiliza una combinación de API postMessage y sessionStorage para hacer que la comunicación sea mucho más fácil y confiable.
Existen diferentes enfoques y cada uno tiene sus propias ventajas y desventajas. Vamos a discutir cada uno:
Almacenamiento local
Pros :
Contras :
Galletas
Pros:
Contras:
Los datos se envían de vuelta al servidor para cada solicitud HTTP (HTML, imágenes, JavaScript, CSS, etc.), lo que aumenta la cantidad de tráfico entre el cliente y el servidor.
Por lo general, se permiten los siguientes:
sessionStorage
Pros:
localStorage
.Contras:
localStorage
, tt funciona en la política del mismo origen . Por lo tanto, los datos almacenados solo estarán disponibles en el mismo origen.PostMessage
Pros:
Contras:
targetOrigin
comprobación de estado de los datos que se transmiten al escucha de mensajes.Una combinación de PostMessage + SessionStorage
Usando postMessage para comunicarse entre múltiples pestañas y al mismo tiempo usando sessionStorage en todas las pestañas / ventanas recién abiertas para persistir la transmisión de datos. Los datos se conservarán mientras las pestañas / ventanas permanezcan abiertas. Por lo tanto, incluso si la pestaña / ventana del abridor se cierra, las pestañas / ventanas abiertas tendrán todos los datos incluso después de actualizarse.
He escrito una biblioteca de JavaScript para esto, llamada AcrossTabs que utiliza la API postMessage para comunicarse entre pestañas / ventanas de origen cruzado y sessionStorage para mantener la identidad de pestañas / ventanas abiertas mientras vivan.
fuente
AcrossTabs
, ¿es posible abrir un sitio web diferente en otra pestaña y obtener los datos de él en la pestaña principal? Tendré detalles de autenticación para el otro sitio web.Otro método que la gente debería considerar usar es Trabajadores Compartidos. Sé que es un concepto de vanguardia, pero puede crear un relé en un Trabajador compartido que sea MUCHO más rápido que el almacenamiento local y que no requiera una relación entre la ventana padre / hijo, siempre y cuando esté en el mismo origen.
Vea mi respuesta aquí para una discusión que hice sobre esto.
fuente
Hay un pequeño componente de código abierto para sincronizar / comunicarse entre pestañas / ventanas del mismo origen (descargo de responsabilidad: ¡soy uno de los contribuyentes!) Basado en él
localStorage
.https://github.com/jitbit/TabUtils
PD: Me tomé la libertad de recomendarlo aquí, ya que la mayoría de los componentes "lock / mutex / sync" fallan en las conexiones websocket cuando los eventos ocurren casi simultáneamente
fuente
He creado una biblioteca sysend.js , es muy pequeña, puedes consultar su código fuente. La biblioteca no tiene dependencias externas.
Puede usarlo para la comunicación entre pestañas / ventanas en el mismo navegador y dominio. La biblioteca usa BroadcastChannel, si es compatible, o un evento de almacenamiento de localStorage.
API es muy simple:
cuando su navegador admite BroadcastChannel, envía un objeto literal (pero de hecho es auto serializado por el navegador) y si no es serializado primero a JSON y deserializado en el otro extremo.
La versión reciente también tiene API auxiliar para crear proxy para la comunicación entre dominios. (requiere un solo archivo html en el dominio de destino).
Aquí está la demostración .
EDITAR :
La nueva versión también admite la comunicación entre dominios , si incluye un
proxy.html
archivo especial en el dominio de destino y laproxy
función de llamada desde el dominio de origen:(proxy.html es un archivo html muy simple, que solo tiene una etiqueta de script con la biblioteca).
Si desea una comunicación bidireccional, debe hacer lo mismo en
target.com
dominio.NOTA : Si implementará la misma funcionalidad usando localStorage, hay un problema en IE. El evento de almacenamiento se envía a la misma ventana, lo que activó el evento y para otros navegadores solo se invoca para otras pestañas / ventanas.
fuente
Creé un módulo que funciona igual que el Broadcastchannel oficial pero tiene fallos basados en localstorage, indexeddb y unix-sockets. Esto asegura que siempre funcione incluso con Webworkers o NodeJS. Ver pubkey: BroadcastChannel
fuente
Escribí un artículo sobre esto en mi blog: http://www.ebenmonney.com/blog/how-to-implement-remember-me-functionality-using-token-based-authentication-and-localstorage-in-a- Aplicación web .
Usando una biblioteca que creé
storageManager
puedes lograr esto de la siguiente manera:También hay otros métodos convenientes para manejar otros escenarios.
fuente
Esta es una
storage
parte del desarrollo de la respuesta de Tomas M para Chrome. Debemos agregar oyenteCargar / guardar elemento en el almacenamiento no se ejecuta este evento - DEBEMOS activarlo manualmente
y ahora, todas las pestañas abiertas recibirán el evento
fuente