Ajax (Asynchronous JavaScript and XML)

Esimerkkiohjelmat

Mitä Ajaxilla voi tehdä

Tunnettuja Ajax-sovelluksia

Ajax-sovelluksen toiminta

Ajax-sovelluksen ja myös aivan tavallisen www-sivun toiminta noudattaa seuraavaa kaavaa:

  1. Selain pyytää WWW-palvelimelta WWW-sivua:
    GET /~tjlahton/sivusto/ HTTP/1.1
    Host: users.jyu.fi
    
    Host-otsake määrää mihin palveluun liittyvää sivua pyydetään. Samalla palvelimella voi olla useita eri sivustoja ja eri osoitteita.
  2. WWW-palvelin kertoo millaista tietoa se palauttaa vastauksena:
    HTTP/1.1 200 OK
    ... lukuisia muita HTTP-otsakkeita ...
    content-type: text/html
  3. WWW-palvelin lähettää varsinaisen sivun sisällön. Sisältö voi olla staattinen tiedosto tai jonkin sovelluksen (CGI, Flask, jne.) tuottama sisältö. Selain ei tiedä mitään siitä miten sisältö on tuotettu
  4. Selain tulkitsee sivun HTML-koodin ja pyytää palvelimelta sivuun liittyvät kuvat ja muut tiedostot kuten javascript-tiedostot ja css-tiedostot
    • GET /~tjlahton/sivusto/tyylit.css HTTP/1.1
    • GET /~tjlahton/sivusto/js/sovellus.js HTTP/1.1
    • GET /~tjlahton/sivusto/kuvat/kuva.png HTTP/1.1
    • Pyynnöt voivat kohdistua eri palvelimiin
  5. Selain vastaa pyyntöihin. Ei voida tietää missä järjestyksessä mikäkin sivuun liittyvä tiedosto latautuu. Useita voidaan käsitellä samaan aikaan. Lataukset tapahtuvat asynkronisesti.
  6. content-type-otsake muuttuu palautettavan sisällön mukaan. content-type-otsakkeessa ilmoitettu mediatyyppi määrittelee mitä siirrettävä data on ja miten sitä pitää käsitellä. WWW-palvelin hoitaa tämän tavallisten tiedostojen kohdalla mutta jos kyseessä on oma sovellus niin silloin pitää itse osata ilmoittaa oikea mediatyyppi.
    • text/html tavallinen html-dokumentti
    • text/plain tekstitiedosto
    • text/xml xml-tiedostot
    • image/png png-kuva
    • text/javascript javascript-tiedostot
    • text/css css-tiedostot
    • application/json json
    • application/xhtml+xml xhtml
    • application/octet-stream binääritiedostot joille ei ole omaa tyyppiä. Käytännössä kaikki tiedostot jotka halutaan vain tallennettavan.
  7. WWW-selain suorittaa sivun sisältöön kirjoitetut tai linkitetyt javascript-sovellukset siinä järjestyksessä kuin ne sivun sisältä löytyvät
  8. Sivun DOM-puuta manipuloivat javascript-sovellukset voidaan suorittaa vasta kun sivun html-sisältö on kokonaan ladattu: $(document).ready()
  9. Sivun kuvien ym. osien latautumista joudutaan odottamaan vielä pitempään. Kaiken latauduttua suoritetaan window.onload-tapahtumaan määritelty ohjelma
  10. Sivuun linkitetty javascript-sovellus voi nyt tehdä lisäpyyntöjä (XHR tai Fetch) WWW-palvelimelle ja ladata esim. lisäsisältöä. Nämä ovat ns. ajax- eli XHR-pyyntöjä eikä selaimen käyttäjä havaitse näitä kuin erikseen Firebugin tms. työkalun avulla.
    • Oletuksena javascript-sovellus voi pyytää lisädataa vain samalta palvelimelta kuin mistä itse sovellus on ladattu (CORS)
    • Ajax-pyyntöjä voi ajatella ohjelmoijan kannalta asynkronisina funktiokutsuina jotka tehdäään verkon ylitse WWW-palvelimella toimivalle sovellukselle
    • Asynkroninen pyyntö eli ajax-pyyntö ei pysäytä ohjelman toimintaa pyynnön toteutuksen ajaksi vaan vastaus pyyntöön tulee joskus määrittelemättömän ajan kuluttua. Vastauksen saapuminen riippuu verkon nopeudesta ja siitä miten suurta tietomäärää liikutetaan ja miten kauan www-palvelimella kestää käsitellä pyyntö. Tämä vastaukseen liittyvä viive täytyy osata huomioida sovelluksen toteutuksessa. Pyyntö voi myös epäonnistua, koska verkko ei toimi tai jotain muuta menee pieleen.
    • Ajax-pyynnössä voi olla mukana parametreja jotka vaikuttavat siihen mitä vastauksena saadaan. Vrt. funktiokutsu ja kutsun parametrit. Kts. RESt
  11. Riippuen selaimen käyttäjän toiminnasta voi javascript-sovellus ladata lisää dataa. Esim. karttasovellus lataisi lisää karttaa sen mukaan miten käyttäjä liikuttelee karttaa. Sivun käyttäjä voi tehdä valintoja joiden perusteella ladataan uutta tietoa ja päivitetään lennosta sivun sisältöä. Esim. käyttäjä syöttää postinumeron niin haetaan ajax-kutsulla tätä vastaava postitoimipaikan nimi.
  12. Sivulla olevat lomakkeet voidaan käsitellä puhtaasti javascriptin avulla ja niiden tiedot voidaan lähettää taustalla www-palvelimelle ja saatu vaste päivittää sivulle ilman, että sivu latautuu selaimessa uudelleen. Vrt. normaali tilanne jossa submit-painikkeen jälkeen lähetetään lomakkeen tiedot www-palvelimelle ja saadaan vastauksena kokonaan uusi sivu.

Miten Ajax-ohjelmia tehdään

Fetch API

Kts. Using Promises

jQuery ja Ajax-operaatiot

XMLHTTPRequestin käyttäminen kannattaa tehdä jQueryn tarjoaman Ajax-rajapinnan kautta, koska rajapinta on helpompi ja yksinkertaisempi käyttää.

/* yksinkertaisin versio, joka korvaa #lataa-id:llä varustetun elementin sisalto.html-dokumentilla. 
Huomaa, että sisalto.html ei tarvitse olla staattinen sivu vaan se voi olla mikä tahansa
sovellus, joka vain palauttaa html-dokumentin
*/
$('#lataa').load('sisalto.html');

$.ajax({
        async: true,
        url: "testi.py",
        data: sisalto,
        dataType: "xml",
        error: virhe,
        processData: true,
        type: "POST",
        success: function(data, textStatus, request){
                alert("ok" + request.responseText);
        }}
);

function virhe(data, textStatus, request) {
 /* täällä käsitellään virhetilanne */
}

XMLHTTPRequest-objekti

XMLHTTPRequest-objektin ominaisuudet kuvataan esim. W3C:n The XMLHttpRequest Object -dokumentissa. Käytä ennemmin Fetch APIa tai jqueryn ajax-kutsuja kuin suoraan XMLHTTPRequest-rajapintaa.

Tärkeimmät metodit:

XMLHTTPRequest-objekti
abort() Keskeytä menossa oleva pyyntö
setRequestHeader("nimi", "arvo") Asettaa pyynnön otsikkotietoja
getResponseHeader("nimi") Palauttaa yhden halutun http-otsakkeen arvon
getAllResponseHeaders() Palauttaa kaikki pyynnölle palautetut http-otsakkeet
open("method", "URL"[, async[, "tunnus"[, "salasana"]]]) Asettaa metodin (POST|GET|HEAD etc.), osoitteen ja mahdollisen käyttäjätunnuksen, salasanan ja tehdäänkö pyyntö asynkronisesti vai ei
send(data) Lähettää pyynnön ja mahdollisen datan
XMLHTTPRequest-objektin ominaisuudet
onreadystatechange Tapahtumankäsittelijä
readyState Objektin tila
  • 0 = alustamaton
  • 1 = lataa (send-metodia on kutsuttu)
  • 2 = http-otsakkeet on saatu
  • 3 = siirretään sisältöä
  • 4 = valmis. sisältö on siirretty
responseText Palautettu data merkkijonona
responseXML Palautettu data DOM-yhteensopivana XML-dokumenttina
status HTTP-statuskoodi (kts. luento 5)
statusText HTTP-statuskoodin mukana tullut mahdollinen teksti esim. virheilmoitus

Huomioitavaa

Muutama asia on huomioitava ennenkuin XMLHttpRequest toimii oikein:

GET

GET-metodia käytettäessä parametrit laitetaan open-metodin url-parametriin. Käytä escape-funktiota tai muuta vastaavaa funktiota ääkkösten yms. korjaamiseksi.

Jos mitään tietoa ei lähetetä ja käytössä on GET-metodi, niin kutsu send(null).

POST

POST-metodia käytettäessä send-metodille annettava data on oltava querystring-muodossa:

nimi=arvo&toinen=arvo&kolomas=jotain

Käytettäessä POST-metodia täytyy mediatyyppi määrätä seuraavalla tavalla:

http_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

Jos mitään tietoa ei lähetetä ja käytössä on POST-metodi, niin kutsu send("").

Vasteen käsittely

Tapahtumankäsittelijässä on tarkistettava readyState-ominaisuudesta mikä on pyynnön vaihe ja status-attribuutista mikä on vasteen statuskoodi.

Kun nämä ovat ok, niin data saadaan responseText tai responseXML-attribuuteista.

responseXML

Jos vaste halutaan XML:nä, on huomioitava seuraavat asiat:

XMLHttpRequestien debuggaus

Pyynnöt ja vasteet saa näkyviin esim. Firebugin Network-välilehdeltä.

Ajax-esimerkkejä

Ajax-sovelluksien virheitä ja ongelmia

Lisätietoa

Linkkejä javascript-kirjastoihin ja Ajax-artikkeleihin.

Käyttäjien kommentit

Kommentoi Lisää kommentti
Kurssimateriaalien käyttäminen kaupallisiin tarkoituksiin tai opetusmateriaalina ilman lupaa on ehdottomasti kielletty!
https://appro.mit.jyu.fi/ties4080/luennot/ajax/
© Tommi Lahtonen (tommi.j.lahtonen@jyu.fi) <https://hazor.iki.fi/>
2021-01-11 13:08:53
Informaatioteknologia - Jyväskylän yliopiston informaatioteknologian tiedekunta