Skip to content

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 ​

mermaid
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) ​

EventBeschreibung
webkatalog-loadedApp wurde geladen
USER_TRACKINGBenutzerinteraktionen
CONTACT_REQUESTKontaktanfrage / Lead (geplant)
ARTICLE_ADDEDArtikel zur Planung hinzugefügt
ARTICLE_REMOVEDArtikel aus Planung entfernt (geplant)
BASKET_UPDATEDWarenkorb aktualisiert
PROPERTY_UPDATE_STARTEDKonfigurationsupdate gestartet
PROPERTY_UPDATEDKonfiguration aktualisiert
PROPERTY_UPDATE_FAILEDKonfigurationsupdate fehlgeschlagen
CONFIGURATION_CHANGEDKonfigurationsänderungen (geplant)
CURRENT_ARTICLEAktueller Artikel (Response)
ERRORNachricht konnte nicht verarbeitet werden

Inbound-Events (Elternseite → WebKatalog) ​

EventBeschreibung
PING_WEBKATALOGHealth-Check / Bereitschafts-Ping
SET_CONFIGLive-Updates (Preisanzeige, Rabatt)
SET_ARTICLEExternen Artikel setzen
PROPERTY_UPDATEDAlias für SET_ARTICLE (Konfigurationsupdate)
REQUEST_CURRENT_ARTICLEAktuellen Artikel abfragen
SET_THEMETheme synchronisieren

Event-Empfang (Elternseite) ​

Grundeinrichtung ​

javascript
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.

javascript
{
  type: 'webkatalog-loaded',
  timestamp: '2024-01-15T10:30:00.000Z'
}

USER_TRACKING ​

Sendet Benutzerinteraktionen für Analytics-Zwecke.

Event-Struktur:

javascript
{
  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:

ActionBeschreibungZusätzliche Daten
article_selectArtikel ausgewähltarticleId, articleName
article_add_to_cartIn den WarenkorbarticleId, articleName, value
article_add_to_wishlistAuf MerkzettelarticleId, 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:

javascript
{
  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 ​

javascript
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:

javascript
{
  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.

javascript
{
  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.

javascript
{
  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:

javascript
{
  type: 'PROPERTY_UPDATE_STARTED',
  timestamp: '2024-01-15T10:30:00.000Z'
}

PROPERTY_UPDATED:

javascript
{
  type: 'PROPERTY_UPDATED',
  article: {
    id: '12345',
    // ... vollständiger Artikel
  },
  timestamp: '2024-01-15T10:30:00.000Z'
}

PROPERTY_UPDATE_FAILED:

javascript
{
  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_ARTICLE ohne article.id)
  • 'Failed to apply external update' (SET_ARTICLE fehlgeschlagen)
  • 'The article was replaced by a newer article load' mit context: '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.

javascript
{
  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.

javascript
{
  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 ​

javascript
{
  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.

javascript
{
  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:

javascript
iframe.contentWindow.postMessage(
  {
    type: 'SET_CONFIG',
    showPrice: false,
    discount: 10
  },
  'https://web.3doffice.de'
);

Unterstützte Konfigurationsoptionen:

OptionTypBeschreibung
showPriceboolean | stringPreisanzeige ein/aus. Akzeptiert true/false oder "true"/"false"
discountnumber | stringRabatt 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: false blendet den Preis sofort aus, ohne Neuladen.
  • discount wirkt 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.

javascript
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.

javascript
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.

javascript
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.

javascript
iframe.contentWindow.postMessage(
  {
    type: 'SET_THEME',
    theme: 'dark'  // oder 'light'
  },
  'https://web.3doffice.de'
);

Alternativ mit darkmode Boolean:

javascript
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 immer event.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) ​

javascript
window.addEventListener('message', (event) => {
  // Origin prüfen
  if (event.origin !== 'https://web.3doffice.de') {
    return;
  }
  
  // Nachricht verarbeiten
  // ...
});

Verhalten ​

  • webkatalog-loaded kommt einmal, sobald die Ansicht bereit ist – nicht erst, wenn ein Artikel geladen ist. PING_WEBKATALOG beantwortet der WebKatalog jederzeit mit webkatalog-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_ARTICLE sendet der WebKatalog PROPERTY_UPDATED mit dem neuen Artikel zurück. PROPERTY_UPDATED wird auch als Eingang akzeptiert (wie SET_ARTICLE) – nicht zurücksenden, sonst entsteht eine Schleife.
  • BASKET_UPDATED kommt pro Klick auf „In den Warenkorb“ und enthält nur diesen Artikel (Menge 1); totalItems zählt die Positionen dieses Artikels inkl. Kinder.
  • REQUEST_CURRENT_ARTICLE ohne geladenen Artikel bleibt unbeantwortet.

3D office WebKatalog 2.5 — ub.unitel GmbH