postMessage-Kommunikation
Die Kommunikation zwischen WebKatalog und Elternseite erfolgt über das HTML postMessage-API.
Übersicht
Der WebKatalog meldet Ereignisse an die Elternseite und nimmt Befehle von ihr entgegen; beides nur, wenn er in einem iFrame läuft.
Funktionsweise
sequenceDiagram
participant Parent as Elternseite
participant WK as WebKatalog
WK->>Parent: webkatalog-loaded (beim Laden)
WK->>Parent: USER_TRACKING (bei Aktionen)
WK->>Parent: ARTICLE_ADDED
WK->>Parent: BASKET_UPDATED
WK->>Parent: CURRENT_ARTICLE (auf Anfrage)
WK->>Parent: ERROR (bei Fehlern)
Parent->>WK: PING_WEBKATALOG (Health-Check)
Parent->>WK: SET_CONFIG (Live-Updates)
Parent->>WK: SET_ARTICLE (Artikel setzen)
Parent->>WK: REQUEST_CURRENT_ARTICLE (aktuellen Artikel abfragen)
Parent->>WK: SET_THEME (Theme synchronisieren)Event-Typen
Outbound-Events (WebKatalog → Elternseite)
| Event | Beschreibung |
|---|---|
webkatalog-loaded | App wurde geladen |
USER_TRACKING | Benutzerinteraktionen |
CONTACT_REQUEST | Kontaktanfrage / Lead (geplant) |
ARTICLE_ADDED | Artikel zur Planung hinzugefügt |
ARTICLE_REMOVED | Artikel aus Planung entfernt (geplant) |
BASKET_UPDATED | Warenkorb aktualisiert |
PROPERTY_UPDATE_STARTED | Konfigurationsupdate gestartet |
PROPERTY_UPDATED | Konfiguration aktualisiert |
PROPERTY_UPDATE_FAILED | Konfigurationsupdate fehlgeschlagen |
CONFIGURATION_CHANGED | Konfigurationsänderungen (geplant) |
CURRENT_ARTICLE | Aktueller Artikel (Response) |
ERROR | Nachricht konnte nicht verarbeitet werden |
Inbound-Events (Elternseite → WebKatalog)
| Event | Beschreibung |
|---|---|
PING_WEBKATALOG | Health-Check / Bereitschafts-Ping |
SET_CONFIG | Live-Updates (Preisanzeige, Rabatt) |
SET_ARTICLE | Externen Artikel setzen |
PROPERTY_UPDATED | Alias für SET_ARTICLE (Konfigurationsupdate) |
REQUEST_CURRENT_ARTICLE | Aktuellen Artikel abfragen |
SET_THEME | Theme synchronisieren |
Event-Empfang (Elternseite)
Grundeinrichtung
window.addEventListener('message', (event) => {
// Herkunft prüfen (empfohlen)
const allowedOrigin = 'https://web.3doffice.de';
if (event.origin !== allowedOrigin) {
return;
}
const data = event.data;
if (!data || typeof data.type !== 'string') {
return;
}
switch (data.type) {
case 'webkatalog-loaded':
console.log('WebKatalog geladen');
break;
case 'USER_TRACKING':
console.log('Tracking:', data.action, data);
break;
case 'CONTACT_REQUEST':
handleContactRequest(data);
break;
case 'ERROR':
console.error('Fehler:', data.errorMessage);
break;
}
});Event-Referenz
webkatalog-loaded
Wird gesendet, sobald der WebKatalog vollständig geladen und bereit ist.
{
type: 'webkatalog-loaded',
timestamp: '2024-01-15T10:30:00.000Z'
}USER_TRACKING
Sendet Benutzerinteraktionen für Analytics-Zwecke.
Event-Struktur:
{
type: 'USER_TRACKING',
action: 'article_select',
articleId: '12345',
articleName: 'Rechtecktisch 160x80',
timestamp: '2024-01-15T10:30:00.000Z'
}Bei article_add_to_cart kommt value (Preis) hinzu.
Gesendete Aktionen:
| Action | Beschreibung | Zusätzliche Daten |
|---|---|---|
article_select | Artikel ausgewählt | articleId, articleName |
article_add_to_cart | In den Warenkorb | articleId, articleName, value |
article_add_to_wishlist | Auf Merkzettel | articleId, articleName |
Geplant (werden derzeit nicht gesendet): page_view, article_configure, property_change, view_3d, view_ar, download_pdf, download_cad, share_article, search, filter, sort, navigation.
CONTACT_REQUEST
Geplant
Wird derzeit nicht gesendet.
Für Kontaktanfragen aus dem WebKatalog (Lead-Generierung) vorgesehen.
Event-Struktur:
{
type: 'CONTACT_REQUEST',
article: {
id: '12345',
name: 'Rechtecktisch 160x80',
manufacturer: 'Hersteller',
series: 'Serie A',
configuration: 'Breite: 1600mm, Tiefe: 800mm, Farbe: Weiß',
price: 599.00,
currency: 'EUR'
},
user: {
name: 'Max Mustermann',
email: 'max@example.com',
phone: '+49 123 456789'
},
message: 'Ich hätte gerne ein Angebot für diesen Tisch.',
timestamp: '2024-01-15T10:30:00.000Z'
}Kontaktanfrage verarbeiten
function handleContactRequest(event) {
const { article, user, message } = event;
// Artikel-Daten
console.log('Angefragter Artikel:', article.name);
console.log('Konfiguration:', article.configuration);
console.log('Preis:', article.price, article.currency);
// Kundendaten
console.log('Kunde:', user.name);
console.log('E-Mail:', user.email);
console.log('Telefon:', user.phone);
// Nachricht
console.log('Nachricht:', message);
// Hier: Eigene Kontaktformular-Logik implementieren
// z.B. an CRM-System weiterleiten
}Hinweis
Der WebKatalog enthält kein eigenes Kontaktformular. Sie müssen das Formular auf Ihrer Website implementieren und die Daten aus dem postMessage-Event vorab ausfüllen.
ARTICLE_ADDED / ARTICLE_REMOVED
Benachrichtigt über Änderungen in der Planung.
ARTICLE_ADDED:
{
type: 'ARTICLE_ADDED',
article: {
id: '12345',
name: 'Rechtecktisch 160x80',
manufacturer: 'Hersteller',
series: 'Serie A',
configuration: 'Breite: 1600mm, Tiefe: 800mm'
},
timestamp: '2024-01-15T10:30:00.000Z'
}ARTICLE_REMOVED:
Geplant
Wird derzeit nicht gesendet.
{
type: 'ARTICLE_REMOVED',
article: {
id: '12345',
name: 'Rechtecktisch 160x80',
manufacturer: 'Hersteller',
series: 'Serie A'
},
timestamp: '2024-01-15T10:30:00.000Z'
}BASKET_UPDATED
Wird bei jedem Klick auf „In den Warenkorb“ gesendet und enthält nur diesen Artikel.
{
type: 'BASKET_UPDATED',
items: [
{
id: '12345',
name: 'Rechtecktisch 160x80',
quantity: 1,
price: 599.00
}
],
totalItems: 1,
timestamp: '2024-01-15T10:30:00.000Z'
}PROPERTY_UPDATE / PROPERTY_UPDATE_STARTED / PROPERTY_UPDATE_FAILED
Benachrichtigt über Konfigurationsänderungen.
PROPERTY_UPDATE_STARTED:
{
type: 'PROPERTY_UPDATE_STARTED',
timestamp: '2024-01-15T10:30:00.000Z'
}PROPERTY_UPDATED:
{
type: 'PROPERTY_UPDATED',
article: {
id: '12345',
// ... vollständiger Artikel
},
timestamp: '2024-01-15T10:30:00.000Z'
}PROPERTY_UPDATE_FAILED:
{
type: 'PROPERTY_UPDATE_FAILED',
reason: 'Beim Aktualisieren des Artikels ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut.',
errorMessage: 'Beim Aktualisieren des Artikels ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut.',
timestamp: '2024-01-15T10:30:00.000Z'
}reason (und gleichlautend errorMessage) ist einer von:
- Text in der Sprache des WebKatalogs (Merkmalsänderung fehlgeschlagen)
'Missing article id'(SET_ARTICLEohnearticle.id)'Failed to apply external update'(SET_ARTICLEfehlgeschlagen)'The article was replaced by a newer article load'mitcontext: 'ARTICLE_REPLACED'(siehe unten)
Auf jedes PROPERTY_UPDATE_STARTED folgt genau ein PROPERTY_UPDATED oder ein PROPERTY_UPDATE_FAILED. Eine Ladeanzeige der Elternseite zwischen beiden endet also immer.
context: 'ARTICLE_REPLACED': Während die Änderung noch lief, wurde ein anderer Artikel geladen (Katalogklick, SET_ARTICLE, Neuladen nach SET_CONFIG). Die Änderung wird verworfen und nicht mehr auf den neuen Artikel angewendet. Das ist kein Serverfehler; die Elternseite sollte keine Fehlermeldung zeigen, sondern auf das ARTICLE_ADDED des neuen Artikels warten.
{
type: 'PROPERTY_UPDATE_FAILED',
reason: 'The article was replaced by a newer article load',
context: 'ARTICLE_REPLACED',
errorMessage: 'The article was replaced by a newer article load',
timestamp: '2024-01-15T10:30:00.000Z'
}CONFIGURATION_CHANGED
Geplant
Wird derzeit nicht gesendet.
{
type: 'CONFIGURATION_CHANGED',
articleId: '12345',
changes: [
{
property: 'Breite',
oldValue: '1400mm',
newValue: '1600mm'
},
{
property: 'Farbe',
oldValue: 'Weiß',
newValue: 'Eiche'
}
],
timestamp: '2024-01-15T10:30:00.000Z'
}CURRENT_ARTICLE
{
type: 'CURRENT_ARTICLE',
article: {
id: '12345',
// ... vollständiger Artikel
},
timestamp: '2024-01-15T10:30:00.000Z'
}ERROR
Wird gesendet, wenn beim Verarbeiten einer Nachricht der Elternseite ein Fehler auftritt. Unbekannte oder unvollständige Nachrichten werden ohne Antwort ignoriert.
{
type: 'ERROR',
errorCode: 'MSG_ERROR',
errorMessage: 'Failed to process message',
context: 'SET_ARTICLE', // Typ der Nachricht
timestamp: '2024-01-15T10:30:00.000Z'
}Nachrichten an den WebKatalog
SET_CONFIG
Live-Updates von Einstellungen:
iframe.contentWindow.postMessage(
{
type: 'SET_CONFIG',
showPrice: false,
discount: 10
},
'https://web.3doffice.de'
);Unterstützte Konfigurationsoptionen:
| Option | Typ | Beschreibung |
|---|---|---|
showPrice | boolean | string | Preisanzeige ein/aus. Akzeptiert true/false oder "true"/"false" |
discount | number | string | Rabatt in Prozent (0-100). Akzeptiert Zahl oder String |
Verhalten:
showPrice: true(vorher ausgeschaltet): Der aktuelle Artikel wird in seiner aktuellen Ausführung neu geladen, denn der Preis kommt nur mit einer Artikelanfrage vom Server. Die Kameraposition bleibt erhalten. Eine laufende Merkmalsänderung wird vorher abgeschlossen.showPrice: falseblendet den Preis sofort aus, ohne Neuladen.discountwirkt sofort: Der Preisreiter zeigt den Listenpreis durchgestrichen und darunter „Ihr Preis · −X %“.
Sicherheit
Verwenden Sie für die Origin-Prüfung immer die vollständige Domain (https://web.3doffice.de) anstatt *.
PING_WEBKATALOG
Health-Check / Bereitschafts-Ping. Der WebKatalog antwortet mit webkatalog-loaded.
iframe.contentWindow.postMessage('PING_WEBKATALOG', 'https://web.3doffice.de');Response: Der WebKatalog sendet webkatalog-loaded zurück.
SET_ARTICLE
Übernimmt das mitgesendete Artikelobjekt (z. B. aus CURRENT_ARTICLE oder PROPERTY_UPDATED) und zeigt es in der 3D-Ansicht. Die Artikeldaten werden nicht neu vom Server geholt; Pflicht ist article.id.
iframe.contentWindow.postMessage(
{
type: 'SET_ARTICLE',
article: {
id: '12345',
manufacturer: 'Hersteller',
program: 'Serie A',
basearticlenumber: 'ABC-123',
// ... vollständiger IArticle
}
},
'https://web.3doffice.de'
);Hinweis: PROPERTY_UPDATED ist ein Alias für SET_ARTICLE und kann synonym verwendet werden.
REQUEST_CURRENT_ARTICLE
Fragt den aktuell ausgewählten Artikel vom WebKatalog ab.
iframe.contentWindow.postMessage(
{
type: 'REQUEST_CURRENT_ARTICLE'
},
'https://web.3doffice.de'
);Response: Der WebKatalog antwortet mit CURRENT_ARTICLE.
SET_THEME
Synchronisiert das Theme der Elternseite mit dem WebKatalog.
iframe.contentWindow.postMessage(
{
type: 'SET_THEME',
theme: 'dark' // oder 'light'
},
'https://web.3doffice.de'
);Alternativ mit darkmode Boolean:
iframe.contentWindow.postMessage(
{
type: 'SET_THEME',
darkmode: true
},
'https://web.3doffice.de'
);Sicherheit
- Der WebKatalog sendet seine Nachrichten mit Ziel-Origin
*an das Elternfenster. Prüfen Sie deshalb auf der Elternseite immerevent.origin. - Der WebKatalog verarbeitet nur Nachrichten seines direkten Elternfensters (
event.source === window.parent); eine Origin-Prüfung gibt es nicht. - Nachrichten enthalten Artikel- und Preisdaten, aber nie den Token.
Empfangsseitige Prüfung (Elternseite)
window.addEventListener('message', (event) => {
// Origin prüfen
if (event.origin !== 'https://web.3doffice.de') {
return;
}
// Nachricht verarbeiten
// ...
});Verhalten
webkatalog-loadedkommt einmal, sobald die Ansicht bereit ist – nicht erst, wenn ein Artikel geladen ist.PING_WEBKATALOGbeantwortet der WebKatalog jederzeit mitwebkatalog-loaded.- Senden Sie Befehle erst nach
webkatalog-loaded. Nachrichten, die früher ankommen, können verloren gehen. - Außerhalb eines iFrames sendet der WebKatalog nichts.
- Nach
SET_ARTICLEsendet der WebKatalogPROPERTY_UPDATEDmit dem neuen Artikel zurück.PROPERTY_UPDATEDwird auch als Eingang akzeptiert (wieSET_ARTICLE) – nicht zurücksenden, sonst entsteht eine Schleife. BASKET_UPDATEDkommt pro Klick auf „In den Warenkorb“ und enthält nur diesen Artikel (Menge 1);totalItemszählt die Positionen dieses Artikels inkl. Kinder.REQUEST_CURRENT_ARTICLEohne geladenen Artikel bleibt unbeantwortet.