AJAX

4IZ268 – Webové technologie

Jirka Kosek

Poslední modifikace: 2024-10-30 17:54:05 UTC

Úvod

Základní principy

  • pro lepší interaktivitu aplikace se neprovádí načítání celých stránek HTML, ale pomocí JavaScriptu se načítají jen potřebná data a zobrazují na stránce

  • data se načítají pomocí objektu XMLHttpRequest (XHR)

  • komunikace probíhá asynchronně

  • data mohou být vrácena v různých formátech

    • XML (AJAX = Asynchronous Javascript and XML)

    • JSON (AJAJ = Asynchronous Javascript and JSON)

    • HTML/text – pro přímé vložení do stránky

  • JavaScript v prohlížeči spolupracuje s backendovým rozhraním

Demo

Historie

  • první XHR implementace byla součástí IE a používala se ve webovém rozhraní Outlooku (OWA) vyvíjeném v letech 1998–2000

  • po roce 2000 začíná přístup používat stále více aplikací

  • od roku 2005 se tento přístup k psaní aplikací pojmenovává jako AJAX (autor pojmu – Jesse James Garrett)

  • postupně dochází ke standardizaci objektu XHR

  • v roce 2015 vzniká novější a snadněji použitelné rozhraní Fetch API, které je široce podporována cca od 2017

Zachování historie

  • AJAX aplikace musí zachovávat model chování, na který jsou uživatelé zvyklí

  • musí fungovat historie prohlížeče (tlačítka Back/Forward)

  • musí být možné vytvářet odkazy a záložky

  • stav aplikace se musí reprezentovat v URL a aplikace musí být schopná počáteční stav obnovit podle tvaru URL

    • dříve se stav ručně reprezentoval na konci URL za znakem #

    • HTML5 přináší rozhraní pro práci s historií prohlížeče (history.pushState() a history.popState())

Objekt XHR

XMLHttpRequest

  • objekt umožňuje odeslání požadavku HTTP z JavaScriptu a následný příjem dat

  • objekt pracuje asynchronně, aby nedocházelo k zamrznutí uživatelského rozhraní

Základní použití

// vytvoření objektu XHR
xhr = new XMLHttpRequest();

// definice funkce volané v případě změny stavu požadavku
xhr.onreadystatechange = function() {

  // je už požadavek vyřízen?
  if (xhr.readyState === XMLHttpRequest.DONE) {

    // je návratový kód v pořádku?
    if (xhr.status === 200) {
      ... zpracování výsledku v xhr.responseText, xhr.responseXML ...
    } else {
      ... server vrátil chybu ...  
    }
  }
}

// nastavení způsobu odeslání požadavku
xhr.open("GET", ...URL...);

// odeslání požadavku
xhr.send();

Stavy požadavku

  • 0 – objekt byl vytvořen

  • 1 – požadavek byl otevřen (metoda open()), ale ještě nebyl odeslán pomocí send()

  • 2 – byly přijaty hlavičky odpovědi

  • 3 – načítají se data odpovědi

  • 4 – data odpovědi jsou načtena/něco selhalo

Čtení výsledku

  • typ vrácených dat lze získat pomocí xhr.responseType

  • podporované typy jsou: arraybuffer, blob, document, json, text

  • xhr.response – vrací výsledek požadavku podle typu

  • xhr.responseText – vrací výsledek požadavku jako textový řetězec

  • xhr.responseXML – vrací výsledek požadavku jako dokument DOM

Formát JSON

  • dnes nejpoužívanější formát pro AJAXové scénáře

  • podmnožina syntaxe JavaScriptu pro zápis datových struktur

  • podporuje pole, objekty, řetězce, čísla, logické hodnoty a null

{ 
  "conferences":
  [
    {
      "name": "XML Prague 2015",
      "start": "2015-02-13",
      "end": "2015-02-15",
      "web": "http://xmlprague.cz/",
      "price": 120,
      "currency": "EUR",
      "topics": ["XML", "XSLT", "XQuery", "Big Data"],
      "venue": {
        "name": "VŠE Praha",
        "location": {
          "lat": 50.084291, 
          "lon": 14.441185
        }
      }
    }, 
    {
      "name": "DATAKON 2014",
      "start": "2014-09-25",
      "end": "2014-09-29",
      "web": "http://www.datakon.cz/",
      "price": 290,
      "currency": "EUR",
      "topics": ["Big Data", "Linked Data", "Open Data"]
    }
  ]
}

Zpracování JSON

  • funkce JSON.parse() umí naparsovat řetězec JSON a vrátí jej jako objekt JavaScriptu

  • čtení dat ze získaného objektu je přímočaré

  • před vznikem JSON.parse() se pro parsování JSON používala funkce eval(), což přinášela různá bezpečnostní rizika

var osoba = JSON.parse(xhr.response);
var result = document.getElementById("result");
result.innerHTML = "Jméno je " + osoba.jmeno + " a věk je " + osoba.vek;

Formát XML

  • v době vzniku AJAXu velice používaný formát

  • XML dokument se automaticky načte do podoby dokumentu DOM

  • bohužel rozhraní DOM není moc pohodlné na čtení dat

  • pro čtení a zpracování složitějších dokumentů lze využít dotazovací jazyk XPath a transformační jazyk XSLT

Zpracování HTML

  • pomocí AJAXu lze přijímat i přímo HTML kód

  • do stránky jej lze vložit např. pomocí innerHTML

  • snadný zdroj pro vložení škodlivého kódu

Fetch API

  • Fetch API – modernější náhrada za XHR

  • fetch(…URL…)
        .then(response => …zpracování odpovědi…)
        .catch(error => …zpracování chyby…)

Odesílání dat

Metody

  • protokol HTTP podporuje několik metod pro odesílání požadavků

  • GET – nejběžnější; čtení dat a odeslání krátkých dat neměnících stav backendu

  • POST – odeslání dat, změna stavu backendu

  • všechny tyto metody lze použít s XHR, liší se způsob jak odeslat data

Ruční odesílání dat

xhr.open("GET", "skript.php?param1=hodnota&param2=hodnota");
xhr.send();
xhr.open("POST", "skript.php");
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send("param1=hodnota&param2=hodnota");
xhr.open("POST", "skript.php");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify(
  {
    param1: hodnota,
    param2: hodnota
  }));

REST API

  • AJAXová aplikace typicky využívá nějaký backend systém pro ukládání/načítání dat

  • nejčastěji se dnes přistupuje přes REST API

  • REST API jednotlivé objekty mapuje na URL

  • pomocí metod protokolu HTTP jsou pak realizovány jednotlivé operace (GET = čtení, DELETE = smazání, POST = změna, PUT = vytvoření) nad objekty

Problémy AJAX

Stav

  • alikace by měla zachovávat „obvyklé“ chování

  • historii lze řešit přepisováním window.location nebo pomocí History API

  • z URL by mělo jít kompletně obnovit stav, aby fungovaly odkazy

Vyhledávače

  • vyhledávače obecně nepodporují JavaScript, takže informace dotahované pomocí AJAX nejsou indexované

  • od roku 2015 Google umí přímo interpretovat JavaScript, nicméně pořád je potřeba podporovat ostatní vyhledávače

  • každopádně je nutné pro vyhledávače nabízet možnost vrácení veškerých dat přímo serverem v podobě statického HTML

  • je potřeba zvážit, zda indexování potřebujeme (aplikace vs. stránky s informacemi)

Bezpečnostní omezení

  • AJAX požadavek lze poslat jen do stejné „domény“ (tzv. „same-origin policy“)

  • server může toto omezení vypnout pomocí hlaviček CORS (cross-origin resource sharing)

  • dříve se omezení obcházelo pomocí JSON-P – data se načetla dynamicky vloženým elementem script

SPA

  • SPA = Single Page Application

  • aplikace využívající myšlenku AJAX extrémním způsobem

  • při prvním požadavku se načte skeleton HTML a celá aplikace v JavaScriptu, veškerá další data se již načítají pouze AJAXem

  • při vhodném doplnění o detekci online/offline stavu, použití lokálních úložišť, … může nahradit nativní aplikace

Izomorfní aplikace

  • aplikace, kde stejný obsah umí vrátit server pro vyhledávače a stejný se zobrazí v prohlížeči pomocí technik AJAXu

  • často vyžaduje duplicitní kód na serveru a klientovi

  • dá se poměrně elegantně vyřešit použitím JavaScriptu na serveru (Node.js) a vhodného frameworku

  • vygenerování kompletního kódu na serveru (tzv. SSR = Server Side Rendering) může být využito i k rychlejšímu zobrazení první stránky v prohlížeči

Další zdroje informací

Povinná četba

Doporučená četba