Kommunikasjon mellom nettleserfaner/-vinduer ved bruk av JavaScript


Hva er den mest pålitelige måten for JavaScript å kommunisere mellom faner/vinduer i samme nettleser? For eksempel, når Fane 2 starter avspilling av lyd, på en eller annen måte vet Fane 1 om dette og kan pause sin spiller.

Jeg bygger et nettsted med en musikkspiller... så akkurat nå, hvis du åpner to faner til nettstedet, kan du starte musikk i begge. Dette er åpenbart dårlig, så jeg prøver å finne en løsning.

Svar #1

For en mer moderne løsning, sjekk ut https://stackoverflow.com/a/12514384/270274

Sitat :

Jeg holder meg til den delte lokale dataløsningen nevnt i spørsmålet ved bruk av localStorage. Det ser ut til å være den beste løsningen når det gjelder pålitelighet, ytelse og nettleserkompatibilitet.

localStorage er implementert i alle moderne nettlesere.

Hendelsen storage utløses når andre faner gjør endringer i localStorage. Dette er ganske praktisk for kommunikasjonsformål.

Referanse:
http://dev.w3.org/html5/webstorage/
http://dev.w3.org/html5/webstorage/#the-storage-event

Svar #2

Oppdater til en moderne løsning, og behold den gamle nedenfor av historiske grunner.

Du kan bruke Broadcast Channel API til å sende og motta meldinger https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API

// Connection to a broadcast channel
const bc = new BroadcastChannel('test_channel');

// Example of sending of a very simple message
// It doesn't have to be a string, it could be a JS object
bc.postMessage('This is a test message.');

For å motta meldingen:

// A handler that only logs the event to the console:
bc.onmessage = function (ev) {
  console.log(ev);
}

og å lukke kanalen:

// Disconnect the channel
bc.close();

DETTE ER DEN GAMLE HISTORISKE MÅTEN Å GJØRE DET PÅ, BRUK METODEN OVER FOR MODERNE NETTLESERE!

Du kan kommunisere mellom nettleservinduer (og faner også) ved hjelp av informasjonskapsler.

Her er et eksempel på avsender og mottaker:

sender.html

<h1>Sender</h1>

<p>Type into the text box below and watch the text 
   appear automatically in the receiver.</p>

<form name="sender">
<input type="text" name="message" size="30" value="">
<input type="reset" value="Clean">
</form>

<script type="text/javascript"><!--
function setCookie(value) {
    document.cookie = "cookie-msg-test=" + value + "; path=/";
    return true;
}
function updateMessage() {
    var t = document.forms['sender'].elements['message'];
    setCookie(t.value);
    setTimeout(updateMessage, 100);
}
updateMessage();
//--></script>

receiver.html:

<h1>Receiver</h1>

<p>Watch the text appear in the text box below as you type it in the sender.</p>

<form name="receiver">
<input type="text" name="message" size="30" value="" readonly disabled>
</form>

<script type="text/javascript"><!--
function getCookie() {
    var cname = "cookie-msg-test=";
    var ca = document.cookie.split(';');
    for (var i=0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(cname) == 0) {
            return c.substring(cname.length, c.length);
        }
    }
    return null;
}
function updateMessage() {
    var text = getCookie();
    document.forms['receiver'].elements['message'].value = text;
    setTimeout(updateMessage, 100);
}
updateMessage();
//--></script>

Svar #3

Jeg tror ikke du trenger informasjonskapsler. Hver dokuments JavaScript-kode kan få tilgang til elementene i det andre dokumentet. Så du kan bruke dem direkte for å dele data.

Ditt første vindu w1 åpner w2 og lagrer referansen

var w2 = window.open(...)

I w2 kan du få tilgang til w1 ved å bruke opener-egenskapen til window.

Svar #4

Det finnes også en eksperimentell teknologi kalt Broadcast Channel API som er spesielt utviklet for kommunikasjon mellom forskjellige nettleserkontekster med samme opprinnelse. Du kan sende meldinger til og motta meldinger fra en annen nettleserkontekst uten å ha en referanse til den:

var channel = new BroadcastChannel("foo");
channel.onmessage = function( e ) {
  // Process messages from other contexts.
};
// Send message to other listening contexts.
channel.postMessage({ value: 42, type: "bar"});

Åpenbart er dette eksperimentell teknologi og støttes ennå ikke i alle nettlesere.

Svar #5

Du kan gjøre dette via Local Storage API. Merk at dette bare fungerer mellom to faner. Du kan ikke ha både sender og mottaker på samme side:

På avsendersiden:

localStorage.setItem("someKey", "someValue");

På mottakersiden:

    $(document).ready(function () {

        window.addEventListener('storage', storageEventHandler, false);

        function storageEventHandler(evt) {
            alert("storage event called key: " + evt.key);
        }
    });

Svar #6

Nedenfor åpner vindu (w1) et annet vindu (w2). Ethvert vindu kan sende/motta meldinger til/fra et annet vindu. Så vi bør ideelt sett verifisere at meldingen stammer fra vinduet (w2) vi åpnet.

I w1

var w2 = window.open("abc.do");
window.addEventListener("message", function(event){
    console.log(event.data);
});

I w2(abc.do)

window.opener.postMessage("Hi! I'm w2", "*");

Svar #7

Kommunikasjon mellom forskjellige JavaScript-utførelseskontekster ble støttet selv før HTML5 hvis dokumentene hadde samme opprinnelse.

Hvis ikke eller du har ingen referanse til det andre Window-objektet, kan du bruke det nye postMessage API som ble introdusert med HTML5. Jeg utdypet litt om begge tilnærmingene i dette svaret på Stack Overflow.

Relaterte artikler