HTML - Web-Nachrichten

-

Arten von Web-Messaging

Channel Messaging

Mit Channel Messaging können zwei oder mehr Browsing-Kontexte (Fenster, Tabs oder iframes) miteinander kommunizieren, auch wenn sie sich auf unterschiedlichen Ursprüngen befinden. Es verwendet ein Message-Channel-Objekt, um eine Verbindung zwischen den Kontexten herzustellen und Nachrichten zwischen ihnen zu senden.

Channel Messaging ist nützlich, wenn Sie eine direkte, bidirektionale Verbindung zwischen Kontexten einrichten müssen. Zum Beispiel können Sie es verwenden, um ein übergeordnetes Fenster ein iframe steuern zu lassen oder zwei Tabs Daten in Echtzeit teilen zu lassen.

Channel Messaging Beispiel

// Im ersten Browsing-Kontext
const channel = new MessageChannel();
const port1 = channel.port1;
const port2 = channel.port2;

// Port2 an den zweiten Browsing-Kontext senden
window.postMessage('init', '*', [port2]);

// Auf Nachrichten an port1 hören
port1.onmessage = (event) => {
  console.log('Nachricht empfangen:', event.data);
};

// Im zweiten Browsing-Kontext
window.onmessage = (event) => {
  if (event.data === 'init') {
    const port2 = event.ports[0];
    port2.onmessage = (event) => {
      console.log('Nachricht empfangen:', event.data);
    };
    port2.postMessage('Hallo vom zweiten Kontext!');
  }
};

Cross-Document Messaging

Cross-Document Messaging, auch als postMessage bekannt, ermöglicht verschiedenen Browsing-Kontexten (Fenstern, Tabs oder iframes) die Kommunikation, auch wenn sie sich auf unterschiedlichen Ursprüngen befinden. Es verwendet die postMessage()-Methode, um ein Nachrichtenereignis an den empfangenden Kontext zu senden, der es dann mit einem Event-Listener verarbeiten kann.

Cross-Document Messaging ist hilfreich, wenn Sie einseitige Nachrichten zwischen Kontexten benötigen. Zum Beispiel, wenn ein übergeordnetes Fenster ein iframe zu einer Aktion auffordern muss oder ein Tab Daten an einen anderen Tab senden muss.

Cross-Document Messaging Beispiel

// Im sendenden Kontext
const targetWindow = window.parent; // Oder window.opener, oder document.getElementById('myIframe').contentWindow
targetWindow.postMessage('Hallo vom Sender!', '*');

// Im empfangenden Kontext
window.addEventListener('message', (event) => {
  if (event.origin === 'http://example.com') {
    console.log('Nachricht empfangen:', event.data);
  }
});

Web Workers

Web Workers führen Skripte im Hintergrund aus, ohne die Seitenleistung zu beeinträchtigen. Sie ermöglichen rechenintensive Verarbeitungen in einem separaten Thread, sodass die Hauptseite reaktionsfähig bleibt.

Web Workers sind nützlich für zeitaufwändige Aufgaben wie komplexe Berechnungen und Datenverarbeitung.

Web Workers Beispiel

// Im Hauptskript
const worker = new Worker('worker.js');
worker.onmessage = (event) => {
  console.log('Nachricht vom Worker empfangen:', event.data);
};
worker.postMessage('Hallo vom Hauptskript!');

// In worker.js
self.onmessage = (event) => {
  console.log('Nachricht im Worker empfangen:', event.data);
  self.postMessage('Hallo vom Worker!');
};

Sicherheitsüberlegungen

Bei der Verwendung von Web Messaging sollten Sie sich potenzieller Sicherheitsrisiken bewusst sein und bewährte Praktiken für eine sichere Implementierung befolgen.

Ein Hauptrisiko bei Web Messaging sind Cross-Site-Scripting-Angriffe (XSS). Wenn Sie die über Nachrichten empfangenen Daten nicht validieren und bereinigen, könnte ein Angreifer schädlichen Code senden, der auf Ihrer Seite ausgeführt wird. Dies könnte es ihm ermöglichen, sensible Daten zu stehlen, Aktionen im Namen des Benutzers auszuführen oder die Kontrolle über die Seite zu übernehmen.

Beispiel: HTML code example for XSS risk

<p>This    is   a   paragraph   with    extra   spaces.</p>

Wenn ein Browser diesen Code rendert, wird der Text so angezeigt:

This is a paragraph with extra spaces.

Um XSS-Angriffe zu verhindern, validieren und bereinigen Sie immer alle über Nachrichten empfangenen Daten. Gehen Sie nicht davon aus, dass die Daten sicher sind, nur weil sie von einem anderen Fenster oder Worker stammen, das Sie kontrollieren. Behandeln Sie alle empfangenen Daten als nicht vertrauenswürdige Eingabe und gehen Sie entsprechend damit um.

Ein weiteres Risiko besteht bei der Verwendung von Web Messaging zur Kommunikation zwischen verschiedenen Ursprüngen. Seien Sie vorsichtig, welchen Ursprüngen Sie vertrauen. Wenn Sie Nachrichten von jedem Ursprung ohne Überprüfung akzeptieren, könnte ein Angreifer Nachrichten von einer schädlichen Website senden, die Ihre Seite dazu bringen, etwas zu tun, was sie nicht tun sollte. Um dieses Risiko zu verringern, überprüfen Sie immer die origin-Eigenschaft des Nachrichtenereignisses und akzeptieren Sie nur Nachrichten von vertrauenswürdigen Ursprüngen.

Bei der Verwendung von Channel Messaging sollten Sie wissen, dass jeder Kontext, der einen Nachrichtenport empfängt, vollen Zugriff auf diesen Kanal hat. Das bedeutet, sie können Nachrichten auf dem Kanal senden und ihn sogar schließen. Teilen Sie daher Nachrichtenports nur mit Kontexten, denen Sie voll vertrauen.

Bei Web Workers besteht ein Hauptrisiko darin, dass ein Worker hängen bleiben oder zu viele Ressourcen verbrauchen könnte, wenn er in einer Endlosschleife stecken bleibt oder versucht, zu viel Arbeit zu erledigen. Um dies zu verhindern, verwenden Sie die Methode Worker.terminate(), um einen Worker bei Bedarf sofort zu stoppen. Strukturieren Sie Ihren Worker-Code so, dass er schnell auf Nachrichten reagiert und vermeiden Sie langwierige Aufgaben.

Beispiel: Using Worker.terminate() method

var myWorker = new Worker('worker.js');

// Terminate the worker after 5 seconds
setTimeout(function() {
    myWorker.terminate();
}, 5000);

Dieser Code stoppt den Worker nach einer festgelegten Zeit, um übermäßigen Ressourcenverbrauch zu verhindern.

Hier sind einige bewährte Praktiken für sicheres Web Messaging:

  • Validieren und bereinigen Sie immer empfangene Nachrichtendaten
  • Akzeptieren Sie nur Nachrichten von vertrauenswürdigen Ursprüngen
  • Seien Sie vorsichtig beim Teilen von Nachrichtenports
  • Verwenden Sie Worker.terminate(), um sich fehlverhaltende Worker zu stoppen
  • Halten Sie Ihren Worker-Code fokussiert und reaktionsschnell
  • Verwenden Sie Web Messaging nicht zum Teilen sensibler Daten, es sei denn, es ist notwendig
  • Verwenden Sie bei Bedarf Verschlüsselung für sensible Daten
  • Testen Sie Ihren Web Messaging-Code gründlich auf potenzielle Schwachstellen

Browser-Unterstützung

Die meisten modernen Webbrowser unterstützen Web Messaging. Dazu gehören Chrome, Firefox, Safari und Internet Explorer 11 und höher. Die WebSocket-API und Server-Sent Events, die für Echtzeit-Messaging verwendet werden, werden ebenfalls von den meisten Browsern unterstützt.

Ältere Browser haben möglicherweise eingeschränkte oder keine Unterstützung für einige Web Messaging-Funktionen. Zum Beispiel:

  • Internet Explorer 8 und älter unterstützen die window.postMessage()-Methode nicht, die beim Cross-Document Messaging verwendet wird.
  • Internet Explorer 10 und älter unterstützen keine Web Workers.
  • Internet Explorer unterstützt kein Channel Messaging.

Wenn Sie ältere Browser unterstützen müssen, müssen Sie möglicherweise Umgehungslösungen oder Fallbacks verwenden. Einige Optionen sind:

  • Für Cross-Document Messaging in alten IE-Versionen können Sie eine Bibliothek wie easyXDM verwenden, die einen Fallback-Transport mit iframes und der location.hash-Eigenschaft bietet.

Beispiel mit der easyXDM-Bibliothek

// Im sendenden Kontext
var socket = new easyXDM.Socket({
  remote: "http://example.com/remote.html",
  onMessage: function(message, origin) {
    console.log("Nachricht empfangen:", message);
  }
});
socket.postMessage("Hallo vom Sender!");

// Im empfangenden Kontext (remote.html)
var socket = new easyXDM.Socket({
  onMessage: function(message, origin) {
    console.log("Nachricht empfangen:", message);
  }
});
  • Für Web Workers in IE10 und älter können Sie die Unterstützung erkennen und einen Fallback bereitstellen, der das Skript stattdessen im Hauptthread ausführt.

Beispiel für Web Workers Fallback

if (typeof(Worker) !== "undefined") {
  // Web Workers werden unterstützt, Worker verwenden
  var worker = new Worker("worker.js");
} else {
  // Web Workers werden nicht unterstützt, Skript im Hauptthread ausführen
  var workerFallbackScript = document.createElement('script');
  workerFallbackScript.src = 'worker.js';
  document.body.appendChild(workerFallbackScript);
}

Für Channel Messaging-Alternativen: Sie können andere Messaging-Techniken wie Cross-Document Messaging oder eine serverbasierte Lösung verwenden, wenn Channel Messaging nicht verfügbar ist.

Es ist wichtig, Ihren Web Messaging-Code in allen Browsern zu testen, die Sie unterstützen möchten. Verwenden Sie Feature-Erkennung, um die Unterstützung zu überprüfen und stellen Sie geeignete Fallbacks bereit, wo nötig, um allen Ihren Nutzern eine gute Erfahrung zu bieten.

Die Browser-Landschaft verbessert sich ständig. Die meisten Nutzer verwenden jetzt moderne Browser mit vielen Funktionen. Obwohl Fallbacks für alte Browser manchmal noch notwendig sein können, werden sie mit der Zeit weniger wichtig, da die Nutzung von Legacy-Browsern weiter abnimmt. Here's the German translation of the provided text:

Praktische Beispiele

Echtzeit-Chat-Anwendung

Der Aufbau einer Echtzeit-Chat-Anwendung zeigt die Stärke von Web Messaging. Hier ist eine Anleitung zum Erstellen einer einfachen Chat-App mit Channel Messaging und Web Workers:

  1. Erstellen Sie die HTML-Struktur für die Chat-Oberfläche, einschließlich eines Eingabefelds für Nachrichten und eines Containers zur Anzeige des Chat-Verlaufs.

  2. Erstellen Sie einen neuen Web Worker zur Verarbeitung und Speicherung von Nachrichten. Dieser Worker empfängt Nachrichten vom Hauptskript, speichert sie und sendet bei Bedarf den aktualisierten Chat-Verlauf zurück.

Beispiel: Web Worker für Chat (chat_worker.js)

let chatHistory = [];

self.onmessage = (event) => {
  if (event.data.type === 'newMessage') {
    chatHistory.push(event.data.message);
    self.postMessage({ type: 'updateHistory', history: chatHistory });
  } else if (event.data.type === 'getHistory') {
    self.postMessage({ type: 'updateHistory', history: chatHistory });
  }
};
  1. Erstellen Sie im Hauptskript einen neuen Channel Messaging-Kanal und senden Sie einen der Ports an den Worker.

Beispiel: Hauptskript (script.js)

const chatWorker = new Worker('chat_worker.js');
const channel = new MessageChannel();
chatWorker.postMessage({ type: 'init', port: channel.port1 }, [channel.port1]);
  1. Richten Sie Event-Listener für die Nachrichteneingabe und die Kanalkommunikation ein. Wenn eine neue Nachricht eingegeben wird, senden Sie sie über den Kanal an den Worker. Hören Sie auf Verlaufsaktualisierungen vom Worker und zeigen Sie diese in der Chat-Oberfläche an.

Beispiel: Event-Listener und Messaging

const messageInput = document.getElementById('messageInput');
const chatContainer = document.getElementById('chatContainer');

channel.port2.onmessage = (event) => {
  if (event.data.type === 'updateHistory') {
    const messagesHTML = event.data.history.map(message => `<p>${message}</p>`).join('');
    chatContainer.innerHTML = messagesHTML;
  }
};

messageInput.addEventListener('keypress', (event) => {
  if (event.key === 'Enter') {
    const message = messageInput.value;
    channel.port2.postMessage({ type: 'newMessage', message });
    messageInput.value = '';
  }
});
  1. Beim Laden der Seite fordern Sie den anfänglichen Chat-Verlauf vom Worker an.

Beispiel: Anforderung des anfänglichen Chat-Verlaufs

chatWorker.postMessage({ type: 'getHistory' });

Mit diesen Schritten haben Sie eine einfache Echtzeit-Chat-Anwendung, die Web Messaging zur Kommunikation zwischen dem Hauptskript und dem Web Worker verwendet.

Domänenübergreifende Kommunikation

Web Messaging kann auch die Kommunikation zwischen verschiedenen Domänen mithilfe von Cross-Document Messaging ermöglichen:

  1. Erstellen Sie im übergeordneten Fenster ein iframe mit dem src-Attribut, das auf die URL der Seite gesetzt ist, mit der Sie kommunizieren möchten.

Beispiel: Übergeordnetes Fenster (parent.html)

<iframe id="myIframe" src="https://example.com/iframe.html"></iframe>
  1. Hören Sie im Skript des iframes auf Nachrichtenereignisse und verarbeiten Sie diese basierend auf dem erwarteten Datenformat.

Beispiel: Iframe-Skript (iframe.js)

window.addEventListener('message', function(event) {
  if (event.origin === 'https://example.com' && event.data.type === 'userData') {
      console.log('Benutzerdaten empfangen:', event.data.value);
   }
});
  1. Holen Sie im Skript des übergeordneten Fensters eine Referenz zum iframe-Fenster und senden Sie Nachrichten mit der postMessage()-Methode.

Beispiel: Skript des übergeordneten Fensters (parent.js)

const iframeWindow= document.getElementById('myIframe').contentWindow;
const userData= { name:'Max Mustermann', age :30 };

document.getElementById("myIframe").addEventListener("load", () =>{
   iframeWindow.postMessage({type :'userData ', value :userData },'https://example.com ');
});

Mit diesem Setup kann das übergeordnete Fenster Nachrichten mit Benutzerdaten an das iframe senden, und das iframe kann auf diese Nachrichten hören und sie entsprechend verarbeiten. Dies ermöglicht eine sichere Kommunikation zwischen zwei Kontexten, auch wenn sie auf verschiedenen Domänen gehostet sind.

Bei der Verwendung von Cross-Document Messaging sollten Sie die Herkunft empfangener Nachrichten überprüfen und sicherstellen, dass sie von vertrauenswürdigen Quellen stammen, um Cross-Site-Scripting (XSS)-Angriffe und andere Sicherheitslücken zu vermeiden.