JavaScript und HTML
Einbinden von JavaScript: Externe Datei
Eigene JavaScript-Datei
- JavaScript kann von mehreren Seiten genutzt werden
- Browser kann Skript cachen
- Normalfall für größere Skripte
<script src="helloworld.js"></script>
Einbinden von JavaScript: Eingebettet
JavaScript direkt in HTML-Datei eingebettet
- Skript gilt nur für diese Datei
- keine Wiederverwendung
<noscript>-Tag für Browser ohne JavaScript-Support
<script>
// <![CDATA[
alert("Hello World!");
// ]]></script>
<noscript><p>Bitte aktivieren Sie JavaScript !</p></noscript>
Einbinden von JavaScript: Inline
JavaScript direkt in HTML-Tags
- Einige HTML-Tags erlauben die Deklaration von Event-Handlern (siehe unten)
- Anstatt eines Funktionsaufrufs kann man hier auch direkt JavaScript einsetzen
<div style="background-color: lightgrey; width: 300px; height: 50px;"
onmouseover="alert('Juhu, getroffen');">Berühr mich</div>
JavaScript als Link-Ziel
- JavaScript kann auch als Ziel eines Links definiert werden
- Anwendungen
- Sprungziele aus Parametern berechnen
- Absende-Button eines Formulars als Link
- Überprüfung der Benutzereingaben vor dem Absenden
<a href="javascript: alert('Ich wurde geklickt!');">
Klick mich
</a>
Verzögertes Laden
JavaScript kann erst auf DOM zugreifen, wenn Seite vollständig geladen ist
- kein-Attribut: Skript wird ausgeführt, wenn der Browser das
<script>-Tag sieht. Weitere Ladevorgänge werden verzögert bis Skript fertig ist defer-Attribut: Skript wird erst ausgeführt, wenn DOM fertigasync-Attribut: Skript wird sofort ausgeführt und Seite wird weiter geladen
<script src="normal.js"></script>
<script defer src="defer.js"></script>
<script async src="async.js"></script>
Ereignisse in HTML - Maus
| Ereignis | Beschreibung |
|---|---|
onclick | Maus wurde geklickt |
ondblclick | Maus wurde doppelt geklickt |
onmousedown | Maus-Knopf ist gedrückt |
onmouseup | Maus-Knopf wurde losgelassen |
onmouseover | Maus betritt ein Element |
onmousemove | Maus bewegt sich im Element |
onmouseout | Maus hat Element verlassen |
Ereignisse in HTML - Tastatur
| Ereignis | Beschreibung |
|---|---|
onkeydown | Taste ist gedrückt |
onkeyup | Taste wurde losgelassen |
onkeypress | Taste würde gedrückt und losgelassen |
Ereignisse in HTML - Formulare
| Ereignis | Beschreibung |
|---|---|
onchange | Daten wurden geändert |
onfocus | Feld hat Fokus |
onblur | Anwender verlässt Feld |
onsubmit | Formular soll abgeschickt werden (false als Rückgabewert verhindert das Absenden) |
onreset | Formular wird zurückgesetzt |
Ereignisse in HTML - Datei
| Ereignis | Beschreibung |
|---|---|
onload | Datei wurde geladen |
onunload | HTML-Datei wurde verlassen |
onabort | Laden der Seite wurde abgebrochen |
Zeitsteuerung von JavaScript
Verzögerte Ausführung
window.setTimeout(funktion, verzögerung);- Verzögerung in Millisekunden
Periodische Ausführung
- Periodendauer in Millisekunden
- Rückgabewert identifiziert Timer-Objekt (es können mehrere parallel laufen)
let p = window.setInterval(funktion, periodendauer);
window.clearInterval (p);
Beispiel: Zeitsteuerung
let counter = 0;
let id;
let handler = function() {
document.getElementById("counter")
.firstChild.nodeValue = counter;
counter++;
}
function startTimerDemo() { id = window.setInterval(handler, 100); }
function stopTimerDemo() { window.clearInterval(id); }
0
Risiko JavaScript
JavaScript hat vollen Zugriff auf die Daten einer Seite
- kann Formularfelder auslesen und verändern
- kann Seite verändern
- kann Daten nachladen
Hieraus würde ein großes Risiko resultieren, wenn beliebige Skripte auf beliebige Inhalte zugreifen können
Sicherheitsmaßnahme: Same Origin Policy
Same Origin Policy
Ein Skript darf nur auf Daten zugreifen, die dieselbe (same) Herkunft (origin) wie es selbst haben
Origin bestimmt sich aus
- Protokoll (http, https, ftp, file, …)
- Host (z. B. www.example.com)
- Port (z. B. 80)
Ausnahme: ein Skript kann anfordern, dass statt des Hosts die Domain verwendet wird (über document.domain)
Beispiel: Same Origin Policy
Skript stammt von http://store.example.com/dir/page.html
| URL | Zugriff |
|---|---|
| http://store.example.com/dir/inner/another.html | JA |
| http://store.example.com/dir2/other.html | JA |
| https://store.example.com/secure.html | Nein |
| http://store.example.com:81/dir/etc.html | Nein |
| http://news.example.com/dir/other.html | Nein |
| http://store.foo.com/dir/page.html | Nein |
CORS
Cross-Origin Resource Sharing (CORS): Erlaubt es, die Same Origin Policy kontrolliert zu umgehen. Es kommt zum Einsatz bei
XMLHttpRequestund Fetch APIs- Web Fonts
- WebGL Texturen
- Bilder und Videos, die auf einen Canvas gezeichnet werden
- CSS-Shapes
Zwei unterschiedliche Arten von CORS- Requests
- Simple Requests
- erfolgen per
GET,HEADoderPOST - haben einen Content-Type von:
application/x-www-form-urlencoded,multipart/form-dataodertext/plain - Preflighted Requests
- alle anderen Requests
- dürfen erst nach einem vorhergehenden
OPTIONS-Request durchgeführt werden (dem Preflight Request) - Preflight-Request fragt den Server mit der Ressource, ob sie geladen werden darf. Wenn OK, dann kommt der richtige Request
CORS-Headers: Client
Der Client fragt die CORS-Regeln mit diesen Headern an
Origin: <origin>
Die Quelle (Serverteil der URL) des Cross-Origin-Zugriffs. Dies ist der Server, von dem das JavaScript geladen wurde, das die Anfrage machtAccess-Control-Request-Method: <method>
Teilt dem Server bei einem Preflight-Request perOPTIONSmit, welche die spätere HTTP-Methode sein wird-
Access-Control-Request-Headers: <field-name> ...
Teilt dem Server bei einem Preflight-Request mit, welche Header der tatsächliche Request tragen wird
CORS-Headers: Server
Der Server sendet einen CORS-Header zurück
Access-Control-Allow-Origin: <origin> | *
Legt die URL (<origin>) fest, von der Ressourcen geladen werden dürfenAccess-Control-Expose-Headers: <header-name> ...
Legt die Header fest, die von JavaScript aus gelesen werden dürfenAccess-Control-Allow-Headers: <header-name>...
Steuert die erlaubten Header bei dem RequestAccess-Control-Allow-Credentials: true
Zeigt an, ob der Request mit Cookies durchgeführt werden kann (3rd-Party-Cookie)
Access-Control-Max-Age: <delta-seconds>
Steuert die Zeit, für die das Ergebnis eines Preflight-Requests im Cache gehalten werden darfAccess-Control-Allow-Methods: <method>[, <method>]*
Spezifiziert, welche Methoden erlaubt sind
Beispiel: GET-Request
GET /resources/public-data/ HTTP/1.1
Host: other.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Referer: http://this.com/simpleXSInvocation.html
Origin: http://this.com
HTTP/1.1 200 OK
Date: Mon, 03 Oct 2022 00:23:53 GMT
Access-Control-Allow-Origin: *
Content-Type: application/xml
...
Beispiel: Preflight-Request
OPTIONS /resources/post-here/ HTTP/1.1
Host: other.com
Connection: keep-alive
Origin: http://this.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type
HTTP/1.1 200 OK
Date: Mon, 03 Oct 2022 01:15:39 GMT
Access-Control-Allow-Origin: http://this.com
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
Vary: Accept-Encoding, Origin
Content-Type: text/plain
Beispiel: Endgültiger Request
POST /resources/post-here/ HTTP/1.1
Host: other.com
X-PINGOTHER: pingpong
Content-Type: text/xml; charset=UTF-8
Referer: http://this.com/examples/preflightInvocation.html
Content-Length: 55
Origin: http://this.com
Pragma: no-cache
Cache-Control: no-cache
<?xml version="1.0"?><person><name>Arun</name></person>
HTTP/1.1 200 OK
Date: Mon, 03 Oct 2022 01:15:41 GMT
Access-Control-Allow-Origin: http://this.com
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 235
Keep-Alive: timeout=2, max=99
Connection: Keep-Alive
Content-Type: text/plain
...
CORS - Ich bin verwirrt…
Fragen
- Wieso erlaubt der Zielserver des Requests den Zugriff?
- Wieso legt nicht der Quellserver (von dem das Skript kam) fest, wohin die Skripte zugreifen dürfen?
- Wie soll mich das vor Cross-Site-Scripting (XSS) schützen?
Antwort: Szenario für das CORS gedacht ist
this.comliefert eine Seite aus- Seite lädt JavaScript von
this.com→ darf aufthis.comzugreifen - Seite lädt JavaScript von anderer Quelle (z. B.
google.com) → darf nicht aufthis.comzugreifen - Auf keinen Fall sollte
google.comfestlegen dürfen, was das Skript darf - CORS-Header von
this.comerlauben dann selektiv den Zugriff fürgoogle.com
Content Security Policy
Content Security Policy erlaubt einem Server zu kontrollieren
- was ein Skript auf der eigenen Seite machen darf
- woher Bilder und andere Ressourcen geladen werden dürfen
- ob Ressourcen nur per HTTPS geladen werden dürfen
- ob Skripte auch direkt in
<script>-Tags oder Event-Handler vorkommen dürfen (→ typisch für XSS)
CSP-Header
CSP wird über Header-Felder kontrolliert
Content-Security-Policy: <policy>
Schaltet CSP ein und legt die Regeln (<policy>) festContent-Security-Policy-Report-Only: <policy>
Schaltet CSP ein und legt die Regeln fest, blockiert die Ressourcen aber nicht, sondern erstellt nur einen Report
CSP-Header: Beispiele
Content-Security-Policy:
default-src 'self'
Alle Ressourcen (Skripte, Bilder, …) müssen von derselben URL kommendefault-src 'self' example.com *.example.com
Ressourcen können zusätzlich noch vonexample.comund allen Subdomains davon kommendefault-src 'self'; img-src *; media-src example.org example.net; script-src userscripts.example.com
Bilder dürfen von jeder Quelle kommen, Andere Medien nur vonexample.orgundexample.net. Skripte ausschließlich vonuserscripts.example.com
Content-Security-Policy:
default-src https://www.example.com
Alle Inhalte müssen per HTTPS geladen werdendefault-src 'self' *.example.com; img-src *
Bilder können von überall geladen werden, alle anderen Inhalte nur von der aktuellen Seitescript-src https://example.com/
Scripts müssen von der Seiteexample.comkommen. Inline-Scripts und Eventhandler sind blockiert