Cross document /Cross domain messaging
avatar

In der App-Entwicklung kommt man oftmals nicht drum rum eine Kommunikation über Domaingrenzen hinweg aufzubauen. Dass dies nicht immer ganz einfach ist, weiß jeder, der sich schon mal mit CORS und JSONP auseinandergesetzt hat. Daher möchte ich in diesem Artikel noch mal eine weitere technische Option mit Hilfe von „window.postMessage()“ vorstellen.

Ich finde den Ansatz recht charmant, da der große Vorteil an dieser Kommunikationsweise darin besteht, dass die Webseite im IFrame in einer anderen Domain gehosted sein darf und trotzdem die Kommunikation sichergestellt ist. Der Zugriff und das Ausführen von Anfragen über Domaingrenzen hinweg ist, normalerweise durch die Same-Origin-Policy (https://de.wikipedia.org/wiki/Same-Origin-Policy) untersagt. Die einzige Möglichkeit eine Kommunikation domainübergreifend zu realisieren ist Cross-Origin Ressource Sharing (CORS) (https://de.wikipedia.org/wiki/Cross-Origin_Resource_Sharing) oder JSONP (https://de.wikipedia.org/wiki/JavaScript_Object_Notation#JSONP), wobei JSONP nur Get-Anfragen unterstützt.

Der Ansatz über window.postMessage() ist also ein weiterer Weg eine „cross origin“-Kommunikation zu ermöglichen.

Eine SharePoint App ist auch nichts anderes als eine Webseite, die mit einem IFrame in den SharePoint integriert wird. Besonders bei einer Provider Hosted APP ist eine domainübergreifende fast immer erforderlich. Aus diesem Grund habe ich Euch nachfolgend eine beispielhafte Kommunikation über window.postMessage() dargestellt. (Mit freundlicher Unterstützung von http://blog.teamtreehouse.com/cross-domain-messaging-with-postmessage)

Fronend-Webseite

    <h1>Frontend</h1>
    <p>
        This document is the front end on http://sharepoint.dev.hansevision.de
    </p>
    <p>
        <button id="send">Send Message</button>
    </p>

<iframe id="receiver" src="http://localhost:10473/receiver.html" width="700" height="400">
        <p>Your browser does not support iframes.</p>
    </iframe>
    <script>
        window.onload = function () {
            var receiver = document.getElementById('receiver').contentWindow;
            var btn = document.getElementById('send');

            function sendMessage(e) {
                e.preventDefault();
                receiver.postMessage('Moin!', '*');
            }
            btn.addEventListener('click', sendMessage);

            // A function to process messages received by the window.
            function receiveMessage(e) {
                // Check to make sure that this message came from the correct domain.
                if (e.origin !== "http://localhost:10473")
                    return;

                //show feedback from backend
                alert('Feedback from backend: ' + e.data);
            }

            // Setup an event listener that calls receiveMessage() when the window
            // receives a new MessageEvent.
            window.addEventListener('message', receiveMessage);
        };

    </script>

Die Methode „postMessage()“ erwartet zwei Parameter:

  • message: Ein Objekt vom Typ String, welches die Nachricht beinhaltet (JSON.stringify(<data>), XML oder was immer ihr übergeben wollt.)
  • targetOrigion: Die URL an die Ihr die Nachricht senden wollt. Diese muss exakt passen (Protokoll, Port und Hostname), ansonsten kommt die Nachricht nicht durch. Wenn „*“ angegeben wird, kann die Nachricht an jede URL gesendet werden, was aber aus Sicherheitsgründen nicht wirklich empfehlenswert ist.

Der Empfänger sollte unbedingt den Sender einer Nachricht geprüft werden, bevor diese verarbeitet wird. (Sicherheitslücke!)

Backend-Webseite

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <script>
        window.onload = function () {
            // Get a reference to the div on the page that will display the
            // message text.
            var messageEle = document.getElementById('message');

            // A function to process messages received by the window.
            function receiveMessage(e) {
                // Check to make sure that this message came from the correct domain.
                if (e.origin !== "http://sharepoint.dev.hansevision.de")
                    return;

                // Update the div element to display the message.
                messageEle.innerHTML = "Message Received: " + e.data;

                window.parent.postMessage('Moin Moin!', 'http://sharepoint.dev.hansevision.de');
            }

            // Setup an event listener that calls receiveMessage() when the window
            // receives a new MessageEvent.
            window.addEventListener('message', receiveMessage);
        }
    </script>
    <title></title>
</head>
<body>

    <h1>Receiver Window</h1>
    <p>
        This document is in the backend
    </p>
    <div id="message"></div>
</body>
</html>

Im Browser sieht diese Lösung dann wie folgt aus:Unbenannt

 

Ich hoffe der Blogbeitrag hat Euch gefallen und konnte Euch weiterhelfen.

Viele Grüße

Andreas

 

 

 

Schreibe einen Kommentar