Webtechnologien Wintersemester 2024

Ajax

  • 1998 Remote-Scripting-Komponente im IE für Outlook Web Access
  • 2005 Der Begriff AJAX wurde von Jesse James Garret in seinem Artikel Ajax: A New Approach to Web Applications bekannt gemacht
  • 2005: Google ( Groups Maps Suggest Mail Finance )

Asynchronous JavaScript and XML

Klassiches Model / Ajax

  • Konzept der asynchronen Datenübertragung zwischen Browser und Server
  • Ermöglicht es, aus einer bereits geladenen HTML-Seite HTTP-Anfragen duchzuführen und die Seite zu verändern, ohne sie komplett neu zu laden
  • Sonst: Request-Response-Paradigma
  • Ajax ist ein Verfahren Teile von angezeigten Web-Seiten direkt zu ersetzen, statt die ganze Seite neu zu laden.
  • Blockiert nicht: Benutzer kann während der Calls weiter arbeiten
  • Erfolgt meist über das nicht standardisierte XMLHttpRequest-Objekt

Vor- / Nachteile

Vorteile

  • Kein Neuladen aufgebauter Seiten
  • Geschwindigkeit
  • Entlastung der Server / Netze
  • Kein Browser-Plugin nötig

Nachteile

  • Umfangreiche Tests erforderlich
  • Zurück-Button *
  • Bookmarks / Suchmaschinen *
  • Polling nötig *
  • Custom Lade-Feedback nötig
  • Barrierefreiheit (Kein JS, kein Content)

* früher, heute nicht mehr

Anwendung

const states = ['nicht init.', 'lade', 'geladen', 'interaktiv', 'fertig'];
const http_request = new XMLHttpRequest();

http_request.onreadystatechange = () => {
   alert(states[http_request.readyState]);
};
http_request.open('GET', 'http://domain.de/folder/file.php', true);
http_request.send(null);
// auch wichtig
http_request.responseText // Antwort des Servers als Textstring
http_request.readyState == 4 // fertig
http_request.status == 200 // alles ok

Quelle: AJAX-Einführung

  • HTML
  • DOM zur Repräsentation der Daten
  • JavaScript zur Manipulation des DOM
  • XMLHttpRequest-Objekt als Bestandteil des Browsers, um Daten asynchroner mit dem Webserver austauschen zu können

Verwendung

  • Instanz der benötigten Klasse erzeugen (nicht als globale Variable, da sich Request sonst überschreiben)
  • dem HTTP Request-Objekt mitteilen, welche JavaScript-Funktion die Antwort abarbeiten soll
  • Der zweite Parameter ist die URL der angeforderten Seite. Aus Sicherheitsgründen können keine Seiten auf 3rd-party Domains angefordert werden. Es muss sichergestellt werden, dass der exakte Domainname auf allen Seiten benutzt wird; andernfalls bekommt man einen ‘permission denied’-Fehler beim Aufruf von open(). Ein beliebter Fallstrick ist der Aufruf einer Seite mittels ‘domain.tld’, wobei die gewünschte Seite jedoch ‘www.domain.tld’ lautet.
  • Der dritte Parameter gibt an, ob der Request asynchron sein soll (default). Wenn er auf true gesetzt ist, wird die JavaScript-Funktion weiter ausgeführt, während die Antwort des Servers noch aussteht. Das ist das A in AJAX.
  • send() bekommt als Parameter den Body, an den Server geschickt wird. Kann alles mögliche sein.
  • READYSTATE_UNINITIALIZED (0): The object has been created, but not initialized (the open method has not been called).
  • READYSTATE_LOADING (1): A request has been opened, but the send method has not been called.
  • READYSTATE_LOADED (2): The send method has been called. No data is available yet.
  • READYSTATE_INTERACTIVE (3): Some data has been received; however, responseText is not available.
  • READYSTATE_COMPLETE (4): All the data has been received.

Anwendung

httpRequest.onreadystatechange = () => { alert(":-)"); };
httpRequest.open('POST', url);
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
httpRequest.send('userName=' + encodeURIComponent(userName));

// andere Funktionen
httpRequest.open(method, url, async, user, password);
httpRequest.withCredentials = true // Cookies oder Auth-Infos mitschicken
httpRequest.abort();
httpRequest.setRequestHeader(name, value);
httpRequest.getResponseHeader(name);
httpRequest.getAllResponseHeaders();

Quelle: AJAX-Einführung

SOP

  • Same-Origin-Policy
  • Sicherheitskonzept, das beispielsweise JavaScript und CSS untersagt, auf Objekte zuzugreifen, die von einer anderen Webseite (Origin) stammen
  • Origin: Kombination aus Protokoll, Domain und Port
  • Stellt ein wesentliches Sicherheitselement in allen modernen Browsern zum Schutz vor Angriffen dar

JSONP

  • JSON mit Padding
  • Übertragung von (JSON-)Daten über Domaingrenzen hinweg
  • Sicherheitsrisiko, da beliebige Inhalte übermittelt werden können
  • Bei strikter REST-Umsetzung nur lesender Zugriff möglich

JSONP

function callMe(text) {
   alert("Dateiinhalt: " + text);
   // andernfalls JSON.parse(text);
}

var script = document.createElement("script");
script.src = "/path/to/my.js";
document.body.appendChild(script);

// my.js
callMe("Lorem ipsum dolor sit amet");

CORS

  • Cross-Origin Resource Sharing
  • Mechanismus, um Webbrowsern Cross-Origin-Requests zu ermöglichen
  • Wird durch speziellen HTTP-Header vom Server gestattet
  • Mit XHR 2 möglich
Access-Control-Allow-Origin: http://example.de

Access-Control-Expose-Headers: X-Custom-Header, X-Another-Header
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: HEAD, PUT, DELETE
  • Simple requests Only uses GET, HEAD or POST. If POST is used to send data to the server, the Content-Type of the data sent to the server with the HTTP POST request is one of application/x-www-form-urlencoded, multipart/form-data, or text/plain.
  • Preflighted requests Anders als simple requests; preflighted requests senden zuerst ein HTTP OPTIONS an die Ressource, um herauszufinden, welche Methoden sicher benutzbar sind. Preflight wird benutzt, wenn nicht GET oder POST (und damit Auswirkungen auf vorhandene Daten möglich sind) oder wenn eigene Header-Felder verwendet werden.

Successor: fetch

fetch('/some/url')
  .then(response => {
     // success
  }).catch(err => {
     // something went wrong
  });

Quelle: deanhume.com

fetch

async function getUser() {
  try {
    const response = await fetch('https://api.example.com/user/1');
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error('Error fetching user:', error);
  }
}

fetch

async function createPost(title, content) {
  try {
    const response = await fetch('https://api.example.com/posts', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ title, content })
    });
    if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Error creating post:', error);
    throw error;
  }
}
  • Support derzeit in Firefox, Chrome und Opera