Uvod

ajax

Ajax je skraćenica od “Asinhroni JavaScript + XML” (iako se danas uglavnom koristi JSON), a predstavlja grupu tehnologija namenjenu za dinamičko kreiranje Web stranica. Korišćenjem AJAX-a poboljšavamo kvalitet interkativnosti sa korisnikom, uz želju da što više liči na desktop aplikacije (prema brzini interakcije). Ideja na kojoj se zasniva Ajax jeste da se stranica na kojoj se odvija Web aplikacija učita samo jednom, a da se svaka dalja komunikacija sa serverom izvršava asinhrono bez blokiranja interfejsa i bez ponovnog učitavanja čitave stranice. Asinhrono ponašanje podrazumeva da nakon interakcije korisnika sa interfejsom, zahtev ka serveru prihvata JavaScript i XMLHttpRequest objekat, koji u pozadini šalje zahteve serveru a prikazujući rezultate kada budu raspoloživi, dok korisnik u međuvremenu može da nastavi sa radom.

Ajax nije bez mana, budući da se Ajax stranice dinamički generišu najveći problem za sajtove je optimizacija za pretraživače. Pretraživači često ne mogu dobro da protumače sajt, što dovodi do problema u indeksiranju sajtova. Sličan problem postoji i sa alatima za analizu posećenosti stranica, jer korisnik može ceo dan da provede na jednoj Ajax stranici, a klasični alati za analizu posećenosti će to protumačiti kao jedno prikazivanje stranice.

XMLHttpRequest objekat

XMLHttpRequest je temelj AJAX-a i predstavlja JavaScript objekat koji se koristi za slanje HTTP zahteva. Dizajniran od strane Microsofta a zatim prihvaćen i od ostalih velikih pretraživača i 2014-te postao standard u W3C.

Svojstva XHR objekta

Svojstvo Opis
readyState Numerička vrednost kojom se opisuje stanje objekta moguća stanja su: 0, 1, 2, 3 i 4

  • stanje 0: početna vrednost objekta nakon kreiranja
  • stanje 1: metoda open() je uspešno izvršena; u ovoj fazi se mogu postavljati hederi zahteva funkcijom setRequestHeader()
  • stanje 2: svi hederi odgovora su pristigli
  • stanje 3: počinje se sa čitanjem dela sa podacima odgovora
  • stanje 4: deo sa podacima odgovora je uspešno učitan ili je došlo do greške
responsType Tekstualni podatak koji odgovara tipu serverskog odgovora moguće vrednosti su: “”, “arraybuffer”, “blob”, “document”, “json” i “text”
response Svojstvo kojim se pristupa telu serverskog odgovora
responseText Vraća odgovor servera kao string
responseXML Vraća odgovor servera kao XML data
status Numerička vrednost koja odgovara HTTP satusu serverskog odgovora. Najviše nas interesuje status 200 – indikacija da je zahtev obradjen uspešno
statusText Tekstualna poruka koja odgovara HTTP poruci serverskog odgovora (npr. “Not Found” or “OK”)
timeout Numerička vrednost nakon koje će HTTP zahtev završiti; trebalo bi da timeout vrednost bude nešto veća nego vreme predviđeno za generisanje odgovora; vrednost responseText svojstva će u tom slučaju biti null
withCredentials Boolean-ova vrednost koja definiše da li je za cross-site Access-Control zahtev potrebni credentials kao što je cookies, autorizovani header ili TLS sertifikat.

Metode XHR objekta

Method Description
abort() Otkazuje trenutni zatev
getAllResponseHeaders() Vraća sve informacije o header-u
getResponseHeader() Vraća specifične informacije o header-u
open(method,url,async,uname,pswd) Funkcija kojom se inicira HTTP zahtev a parametri koje prihvata su:

  • Metod: POST, GET, HEADER, PUT, DELETE
  • ULR je url servera kojem se šalje zahtev
  • Asinhronost može biti true ili false u zavisnosti od toga da li zahtev realizuje asinhrono ili sinhrono
  • Korisničko ime i šifra su opcioni argumenti koji se navode ukoliko su potrebni za pristup serveru
send() Metoda kojom se šalju podaci na server (ako imamo šta da pošaljemo)
setRequestHeader(header, value) Pri slanju podataka dodaje label/value par u header-u. Mora da se pozove posle open() a pre send() metode

Postupak

a) Kreiranje objekta

Kreira se pozivanjem konstruktora XMLHttpRequest:

b) Event handler i callback funkcija

Dogadjaji (events) vezani za XHR objekat

Dogadjaji vezani za XHR objekat mogu biti:

Tip Opis Broj pojavljivanja Kada
onreadystatechange Promena stanja. Pri svakoj promeni stanja
loadstart Proces je započet. Jednom Prvo
progress Proces je u toku nula ili više Kada je loadstart završen.
error Proces ima grešku Jednom ili nijednom Posle pucanja poslednjeg procesa.
abort Proces je prekinut. Jednom ili nijednom
load Uspešan proces Jednom ili nijednom Izvrsava se kada odgovor stigne u celosti umesto provere za readyState==4
loadend Ceo proces je završen Jednom Aktivira se posle neke greške, namernog prekida (abort) ili kada je load završen uspešno.

Primeri

onreadystatechange

Ovaj način je najstariji i podržan je u svim browserima, kod njega eventHandler prati svaku promenu stanja objekta (readyState) i “okida” pri svakoj promeni stanja.

onload

Prethodni slučaj “okida” dogadjaj pri svakoj promeni stanja objekta, medjutim nas najčešće interesuje samo kada se stanje objekta promeni na vrednost: readyState == 4. Ukoliko vam nisu od značaja informacije o drugim stanjima i želite da smanjite “okidanje” nepotrebnih dogadjaja možda je bolji noviji i “moderniji” pristup kada se generiše samo jedan dogadjaj “load” kada server odgovori:

ili

onerror

Pored “load” eventListener-a možemo da osluškujemo i network-level error-e:

Ili čak da se error uzme sa stack-a:

c) Definisanje parametara konekcije

Nakon kreiranja XMLHttpRequest objekta, potrebno je definisati osnovne parametre za komunikaciju. Ova metoda ne šalje zahtev web server-u, već čuva svoje argumente za kasnije slanje request-a.

  • Metod

    Metode koje mogu da se koriste su: POST, GET, HEADER, PUT, DELETE.
    GET metoda šalje zahtev i podatke kroz url, kod nje se request se može keširati, zahtev ostaje u istoriji pretraživača i može se bookmark-ovati. Mana je ograničena veličina podataka koja se može proslediti kroz URL, kao i vidljiost podataka u URL-u (čitaj “nebezbednost“). Zbog čega se ova metoda i ne koristi za slanje važnih podataka.

    POST metode ne šalje podatke kroz URL već kroz atribut send() metode, pa je bezbednija i koristi se kada treba slati poverljive podatke (najčešće koje unosi korisnik). POST metoda se koristi i onda kada treba poslati veću količnu podataka s obizrom da nema ograničenu veličinu podatka kao što je to slučaj kod GET metode. Medjutim kod ove metode zahtev se nemože keširati, ne ostaje u istoriji browser-a pa se ne može ni bookmark-ovati.
    HEAD metoda traži od servera header-e sa navedene URL adrese bez sadržaja dokumenta (koristi se npr. da bi se proverio datum izmene resursa).

  • URL

    ULR je url servera kojem se šalje zahtev

  • Asinhronost zahteva

    Ovim parametrom se definiše asinhronost zahteva. Može biti true ili false. Ukoliko se izostavi ili definiše kao TRUE onda je zahtev asinroni.

    NAPOMENA:
    XMLHttpRequest zahtev može biti i sinhroni ali se to ne preporučuje jer ukoliko sever ne pošalje odgovor, metoda send() može da zablokira rad browser-a. Ne postoji “magično dugme” koje zaustavlja XMLHttpRequest, kao ni maksimalno vreme čekanja pa JavaScript engine ne dozvoljava zaustavljanje izvršenja zahteva kad je jednom poslat.

  • User Name i Password

    Korisničko ime i šifra su opcioni argumenti koji se navode ukoliko su potrebni za pristup serveru

d) Definisanje podataka zaglavlja (header-a)

Sintaksa

Sa metodom “setRequestHeader()” možemo da definišemo neke vrednosti u zaglavlju zahteva. Najčešće se koristi pri slanju podataka na server sa POST metodom. Parametar metode je u vidu “key, value” para.

NAPOMENA:
Metoda “setRequestHeader()” mora da bude smeštena izmedju open() i send() metode.

Šta je enkodovanje?

Postoje tri načina na koji se može enkodovati:

Value Description
application/x-www-form-urlencoded Default-no ponašanje, svi znakovi se kodiraju pre slanja (razmaci se pretvaraju u “+” simbole, a specijalni znakovi se pretvaraju u ASCII HEX vrednosti. Ustvari podatak je query string koji se sastoji od parova ime/vrednostodvojenih sa znakom “&”, gde su imena odvojena od vrednosti znakom jednako “=”, ukoliko ima specijalnih znakova oni prebačeni u ASCII HEX vrednosti.
multipart/form-data Nijedan znak nije kodiran. Ova vrednost je potrebna kada koristite obrasce sa kontrolom za otpremanje datoteka
text/plain Prostori se pretvaraju u “+” simbole, ali ne postoje drugi posebni znaci

Kroz parametar metode “setRequestHeader()” možemo da pošaljemo serveru način na koji je enkodovan poslati podatak.

Saveti za izbor tipa enkodovanja

Tip sadržaja “application/x-www-form-urlencoded” se koristi u većini slučajeva, osim za slanje velikih količina binarnih podataka ili teksta koji sadrže ne-ASCII znakove jer je za to neefikasan. A “multipart/form-data” treba koristiti za podnošenje formulara koji sadrže datoteke, ne-ASCII podatke i binarne podatke.

e) Pripema podataka za slanje

U slučaju slanja podataka potrebno je pripremiti podatke u obliku koji je pogodan za slanje.

Serijalizovanje podataka u “query string”

a) Jednostavan podatak

Ako je podatak jednostavan šalje se kao query string koji se sastoji od parova ime/vrednost odvojenih sa znakom “&”, gde su imena odvojena od vrednosti znakom jednako “=”, a ukoliko ima specijalnih znakova oni prebačeni u ASCII HEX vrednosti.

b) Objekat

Ukoliko je u pitanju objekat/JSON potrebno je prvo ga prebaciti u string.

Nakon čega enkodovati dobijeni string:

Decodovanje i encodovanje možete proveriti preko online servisi kao što je https://www.freeformatter.com/url-encoder.html ili http://www.url-encode-decode.com/.

Primer

Ovaj snippet ima sličnu funkcionalnost kao jQuery metoda serialize()

Seriajalizovanje podataka u niz

Ovaj snippet ima sličnu funkcionalnost kao jQuery metoda serializeArray()

f) Slanje zahteva

Iniciranje povezivanja pripremljenog i definisanog zahteva sa serverom se vrši sa metodom send(). Atribut metode send(atribut) možemo da koristim za prosledjivanje podataka serveru. Upravo kod POST metode je to glavni princip slanja podataka. Jednostavno sve “pripremljenje” podatke šaljemo kao atribut metode “send”. Madjutim pošto kod GET metode sve informacije šaljemo kroz URL, onda kod nje ne koristimo tu mogućnost slanja kroz atribut, već atribut definišemo sa null send(null) ili ga jednostavno ne popunimo.

g) Odgovor servera

Status zahteva

Statusu našeg zahteva kao odgovor servera se pristupa pomoću svojstva XMLHttpRequest objekta status

a tekstu statusa sa:

String odgovor

Odgovoru servera u vidu “string niza” se pristupa preko svojstva responseText

NAPOMENA:
XMLHttpRequest nema direktno svojstvo za odgovor servera u JSON formatu, pa je zato potrebno parsirati odgovor:
JSON.parse(xhr.responseText);

XML odgovor

Odgovoru servera koji je neki XML se pristupa sa responseXML

HTTP zaglavlje serverskog odgovora

Pristup svim zaglavljima koje vraća web server je uz pomoć metode getResponseHeader() :

Primeri

OBJAŠNJENJE:
U primerima koristim online resurs myjson.com za brzo generisanje REST endpoint-a.

a) Dobijanje podataka

Primer br.1

JSON fajlu sačuvanog na sajtu http://myjson.com/ pristupam preko endpointa: https://api.myjson.com/bins/erxi9. Sa ajax request-om ka endpoint-u dobijam sledeći sadržaj:

U ovome primeru se štampaju sve osobe koje zadovaoljavaju izabranu poziciju:

See the Pen Promise primer by Web programiranje (@chos) on CodePen.

Primer br.2

Za ovaj primer koristim generisani endpoint https://api.myjson.com/bins/amz5t.

See the Pen Ajax GET by Web programiranje (@chos) on CodePen.

b) Slanje podataka

Primer

Primer: slanje podataka iz forme

c) Slanje fajlova

Ajax i HTML5 FormData interfejs

Korišćenje HTML5 interfejsa FormData prilično olakšava rad sa formama, jer je u stanju da pokupi sve vrednosti input-a u formi u vidu key/value parova. Još jedna prednost nad standardnim metodom vezana je za olakšano pisanje serverskog koda. Sa standardnim metodom moramo dodati određeni kod na strani servera koji bi dolazne podatke obradio na specijalizovan način, dok sa FormData to nije potrebno, jer je poslati kod standardizovan i debug-ovan!

NAPOMENA:
U formi svi HTML input tag-ovi moraju da imaju atribut ‘name’, jer je potreban da bi omogućio pristup vrednostima inuput-a.

Syntax

Kada želimo da pokupimo sve vrednosti inputa forme onda koristimo:

FormData objekat se popunjava sa keys/values parovima. JavaScript koristi name svojstvo za svaki element forme kao keys i pridružuje mu enkodovanu vrednost ulaza. Ukoliko želimo da FormData objektu pridružimo samo jedan input (tj. jedan par key/value), onda možemo da koristimo i sledeću syntax-u:

Primer:

MDN snippet

Ovaj snippet preporučen od MDN pokriva sve moguće načine slanja podataka

Primena GET metodu

Primena uz POST metodu (application/x-www-form-urlencoded)

Primena uz POST metodu (multipart/form-data)

Podelite:

Ostavite komentar