Christian Wenz | Arrabiata Solutions GmbH
@chwenz
Kommunikations-APIs von
JavaScript und HTML5
Agenda
• Wider der Same-Origin Policy
– CORS
• Kommunikation im Browser
– Messaging API
– Worker
• Performante Kommunikation
– SSE, WebSockets, WebRTC, …
Status Quo
• GET-Requests mit src-Attribut möglich
– Ohne Einschränkungen
– Kein Zugriff auf Rückgabe
• Jedes (vom Browser unterstützte) HTTP-
Verb via XMLHttpRequest
– HTTP-Header und -Body können angegeben
werden
– Beschränkt durch SOP (Same-Origin Policy)
• Protokoll, Domain, Port
• Verwendet immer noch HTTP
Same-Origin Policy (SOP)
• Origin: vgl.
http://tools.ietf.org/html/rfc6454
• Protokoll, Domain, Port
• Ausgenommen: src-Attribut – etwa bei
<script>!
Same-Origin Policy (SOP) (2)
• http://example.com/
• http://example.com:80/
• http://example.com/path/file
• http://example.com/
• http://example.com:8080/
• http://www.example.com/
• https://example.com:80/
• https://example.com/
• http://example.org/
• http://webtechcon.de/
CORS
• Cross-Origin Resource Sharing
• Umgeht die Same Origin Policy
• Es gibt allerdings Einschränkungen
– Spezifischer Content-type-Header
(teilweise)
– Origin-Header wird automatisch gesetzt
– Server verwendet den Header Access-
Control-Allow-Origin (Wert muss * sein
oder der des Origin-Headers)
Lessons Learned
Opfer
(Client)
Angreifer
(Website)
Andere
Website
1) HTTP-Anfrage
2) Schickt JavaScript
3) HTTP-Anfrage
CORS (2)
• Fortgeschrittener Ansatz: Preflighted
Requests (z.B. für POST-Anfragen, um
CSRF zu vermeiden)
• Nettes Flussdiagramm bei
HTML5Rocks:
http://www.html5rocks.com/static/images
/cors_server_flowchart.png
Messaging API
• Einfacher Cross-Domain-Mechanismus,
um Daten zu senden und zu empfangen
• Funktioniert überall ab IE8+
• Senden:
– Auf anderes Fenster zugreifen (z.B.
contentWindow-Eigenschaft eines Iframes)
– Daten senden mit der Methode postMessage()
– Aus Sicherheitsgründen muss der Ursprung
der Zielsite als zweiter Parameter angegeben
werden
Messaging API (2)
• Empfangen:
– Auf das message-Ereignis warten.
– Eventparameter enthält die gesendeten
Daten (Eigenschaft data) und denn
Ursprung des Senders (Eigenschaft origin)
– Mit postMessage() können Daten zurück
an den Sender geschickt werden
– Dort analog auf das Ereignis message
lauschen
Shared Worker
• Client:
– new SharedWorker
– port.start()
– port.postMessage()
• Worker:
– self.onconnect = function(e) {
var port = e.ports[0];
}
• Aktuell nur Firefox/Chrome
Service Worker
• Worker als Basis für Push-Notifications,
Background-Sync und mehr
• Firefox und Chrome – bald Edge
• Aktueller Stand:
https://jakearchibald.github.io/
isserviceworkerready/
Lebenszyklus
• https://developers.google.com/web/fundamentals/getting-started/primers/service-workers
Push API
• Senden von Informationen an eine
Webanwendung
• Auch wenn Seite nicht im Vordergrund (oder
gar nicht geladen)
• Basiert auf Service Worker
• Firefox/Chrome (jeweils Desktop)
Notification API
• „Toast“-Anzeige einer Meldung
• Bestimmte, aber eingeschränkte
Layoutmöglichkeiten
• Häufig mit zugehörigem Service Worker
• Demo:
https://github.com/chrisdavidmills/push-
api-demo
Server-Sent Events
• JavaScript-API für Long Polling Requests
• Server schickt dauernd Daten, der Browser
verarbeitet sie sukzessive
• Schritt 1: Datenquelle abonnieren
– var es = new EventSource("polling.ext");
• Schritt 2: auf das Ereignis message lauschen
– es.onmessage = function(ev) {
console.log(ev.data);
};
• Klappt überall – außer im IE 
Stream-Format
• Content-type: text/event-stream
• Felder: id, data, event, retry (alle optional!)
• Format: <field>: <value>
• Leerzeilen zwischen Feldern
• id: 123
data: abc
id: 456
event: def
Wiederaufbau der Verbindung
• Browser verbindet sich alle paar
Sekunden neu (außer der Streamwert
retry gibt etwas anderes an)
• Browser schickt den HTTP-Header
Last-Event-ID falls der Server zuvor
eine ID verschickt hatte
• Ermöglicht es dem Server nur neue
Daten zu schicken
Web Sockets
• Full-Duplex-Kommunikation
• Umgeht ein paar der Nachteile von
HTTP (Metadaten werden mit jeder
Anfrage verschickt, Neuaufbau der
Verbindung, etc.)
• Klappt in allen modernen Browsern (IE
ab Version 10)
HTTP-Handshake
• Request:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
• Response:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
API für Web Sockets
• Server: hängt von der jeweiligen Technologie ab
• Client:
– var w = new WebSocket("ws://server:1234");
– w.onopen = function(ev) {
w.send("Hi!");
}
w.onmessage = function(ev) {
console.log(ev.data);
}
Websocket-Server mit node.js
var webSocketServer = require("websocket").server;
server.listen(webSocketsServerPort);
var wsServer = new webSocketServer({
httpServer: server
});
wsServer.on('request', function(request) {
…
});
Socket.IO
• Es gibt zahlreiche Protokollversionen von Web
Sockets
• In dem Fall bietet es sich an eine Abstraktionsschicht
zu nutzen, die auch Polyfills für ältere Browser bietet,
z.B. Socket.IO (http://socket.io/).
• Server:
– var io = require("socket.io").listen(1234);
• Client:
– var ws = io.connect("http://127.0.0.1:1234");
WebRTC
• http://www.webrtc.org/
• Ursprünglich Open-Source-Projekt von
Google
• Mittlerweile im W3C-
Standardisierungsprozess
(http://www.w3.org/2011/04/webrtc/)
• Anwendungsfälle: Sprach- und
Videokommunikation, P2P
WebRTC-APIs
• MediaStream/getUserMedia(): Zugriff
auf Daten-Streams
• RTCDataChannel: Datenkanal
• RTCPeerConnection: P2P-Verbindung
für Audio und Video
getUserMedia()
• Beispiel Video:
navigator.getUserMedia(
{ video: true }),
function(stream) {
videoElement.src =
window.URL.createObjectURL(stream);
// oder: srcObject
},
function (error) {});
Screenshots
• Aktueller Video-Frame kann in Canvas
„gezeichnet“ werden
• ctx.drawImage(video, 0, 0,
video.clientWidth, video.clientHeight);
WebRTC-Beispiele
• Firefox Hello
• http://apprtc.appspot.com/
• Plugin-basierte Dienste (Skype
innerhalb von Facebook, Google
Hangouts)
Danke!
• Email: christian.wenz@arrabiata.de
• Twitter: @chwenz

Kommunikations-APIs von JavaScript (International PHP Conference/WebTechCon 2016 Fall)

  • 1.
    Christian Wenz |Arrabiata Solutions GmbH @chwenz Kommunikations-APIs von JavaScript und HTML5
  • 2.
    Agenda • Wider derSame-Origin Policy – CORS • Kommunikation im Browser – Messaging API – Worker • Performante Kommunikation – SSE, WebSockets, WebRTC, …
  • 3.
    Status Quo • GET-Requestsmit src-Attribut möglich – Ohne Einschränkungen – Kein Zugriff auf Rückgabe • Jedes (vom Browser unterstützte) HTTP- Verb via XMLHttpRequest – HTTP-Header und -Body können angegeben werden – Beschränkt durch SOP (Same-Origin Policy) • Protokoll, Domain, Port • Verwendet immer noch HTTP
  • 4.
    Same-Origin Policy (SOP) •Origin: vgl. http://tools.ietf.org/html/rfc6454 • Protokoll, Domain, Port • Ausgenommen: src-Attribut – etwa bei <script>!
  • 5.
    Same-Origin Policy (SOP)(2) • http://example.com/ • http://example.com:80/ • http://example.com/path/file • http://example.com/ • http://example.com:8080/ • http://www.example.com/ • https://example.com:80/ • https://example.com/ • http://example.org/ • http://webtechcon.de/
  • 6.
    CORS • Cross-Origin ResourceSharing • Umgeht die Same Origin Policy • Es gibt allerdings Einschränkungen – Spezifischer Content-type-Header (teilweise) – Origin-Header wird automatisch gesetzt – Server verwendet den Header Access- Control-Allow-Origin (Wert muss * sein oder der des Origin-Headers)
  • 7.
  • 8.
    CORS (2) • FortgeschrittenerAnsatz: Preflighted Requests (z.B. für POST-Anfragen, um CSRF zu vermeiden) • Nettes Flussdiagramm bei HTML5Rocks: http://www.html5rocks.com/static/images /cors_server_flowchart.png
  • 9.
    Messaging API • EinfacherCross-Domain-Mechanismus, um Daten zu senden und zu empfangen • Funktioniert überall ab IE8+ • Senden: – Auf anderes Fenster zugreifen (z.B. contentWindow-Eigenschaft eines Iframes) – Daten senden mit der Methode postMessage() – Aus Sicherheitsgründen muss der Ursprung der Zielsite als zweiter Parameter angegeben werden
  • 10.
    Messaging API (2) •Empfangen: – Auf das message-Ereignis warten. – Eventparameter enthält die gesendeten Daten (Eigenschaft data) und denn Ursprung des Senders (Eigenschaft origin) – Mit postMessage() können Daten zurück an den Sender geschickt werden – Dort analog auf das Ereignis message lauschen
  • 11.
    Shared Worker • Client: –new SharedWorker – port.start() – port.postMessage() • Worker: – self.onconnect = function(e) { var port = e.ports[0]; } • Aktuell nur Firefox/Chrome
  • 12.
    Service Worker • Workerals Basis für Push-Notifications, Background-Sync und mehr • Firefox und Chrome – bald Edge • Aktueller Stand: https://jakearchibald.github.io/ isserviceworkerready/
  • 13.
  • 14.
    Push API • Sendenvon Informationen an eine Webanwendung • Auch wenn Seite nicht im Vordergrund (oder gar nicht geladen) • Basiert auf Service Worker • Firefox/Chrome (jeweils Desktop)
  • 15.
    Notification API • „Toast“-Anzeigeeiner Meldung • Bestimmte, aber eingeschränkte Layoutmöglichkeiten • Häufig mit zugehörigem Service Worker • Demo: https://github.com/chrisdavidmills/push- api-demo
  • 16.
    Server-Sent Events • JavaScript-APIfür Long Polling Requests • Server schickt dauernd Daten, der Browser verarbeitet sie sukzessive • Schritt 1: Datenquelle abonnieren – var es = new EventSource("polling.ext"); • Schritt 2: auf das Ereignis message lauschen – es.onmessage = function(ev) { console.log(ev.data); }; • Klappt überall – außer im IE 
  • 17.
    Stream-Format • Content-type: text/event-stream •Felder: id, data, event, retry (alle optional!) • Format: <field>: <value> • Leerzeilen zwischen Feldern • id: 123 data: abc id: 456 event: def
  • 18.
    Wiederaufbau der Verbindung •Browser verbindet sich alle paar Sekunden neu (außer der Streamwert retry gibt etwas anderes an) • Browser schickt den HTTP-Header Last-Event-ID falls der Server zuvor eine ID verschickt hatte • Ermöglicht es dem Server nur neue Daten zu schicken
  • 19.
    Web Sockets • Full-Duplex-Kommunikation •Umgeht ein paar der Nachteile von HTTP (Metadaten werden mit jeder Anfrage verschickt, Neuaufbau der Verbindung, etc.) • Klappt in allen modernen Browsern (IE ab Version 10)
  • 20.
    HTTP-Handshake • Request: GET /chatHTTP/1.1 Host: server.example.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw== Sec-WebSocket-Protocol: chat, superchat Sec-WebSocket-Version: 13 Origin: http://example.com • Response: HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk= Sec-WebSocket-Protocol: chat
  • 21.
    API für WebSockets • Server: hängt von der jeweiligen Technologie ab • Client: – var w = new WebSocket("ws://server:1234"); – w.onopen = function(ev) { w.send("Hi!"); } w.onmessage = function(ev) { console.log(ev.data); }
  • 22.
    Websocket-Server mit node.js varwebSocketServer = require("websocket").server; server.listen(webSocketsServerPort); var wsServer = new webSocketServer({ httpServer: server }); wsServer.on('request', function(request) { … });
  • 23.
    Socket.IO • Es gibtzahlreiche Protokollversionen von Web Sockets • In dem Fall bietet es sich an eine Abstraktionsschicht zu nutzen, die auch Polyfills für ältere Browser bietet, z.B. Socket.IO (http://socket.io/). • Server: – var io = require("socket.io").listen(1234); • Client: – var ws = io.connect("http://127.0.0.1:1234");
  • 24.
    WebRTC • http://www.webrtc.org/ • UrsprünglichOpen-Source-Projekt von Google • Mittlerweile im W3C- Standardisierungsprozess (http://www.w3.org/2011/04/webrtc/) • Anwendungsfälle: Sprach- und Videokommunikation, P2P
  • 25.
    WebRTC-APIs • MediaStream/getUserMedia(): Zugriff aufDaten-Streams • RTCDataChannel: Datenkanal • RTCPeerConnection: P2P-Verbindung für Audio und Video
  • 26.
    getUserMedia() • Beispiel Video: navigator.getUserMedia( {video: true }), function(stream) { videoElement.src = window.URL.createObjectURL(stream); // oder: srcObject }, function (error) {});
  • 27.
    Screenshots • Aktueller Video-Framekann in Canvas „gezeichnet“ werden • ctx.drawImage(video, 0, 0, video.clientWidth, video.clientHeight);
  • 28.
    WebRTC-Beispiele • Firefox Hello •http://apprtc.appspot.com/ • Plugin-basierte Dienste (Skype innerhalb von Facebook, Google Hangouts)
  • 29.