Kako podesiti pametne telefone i računare. Informativni portal

Slanje POST zahtjeva putem JavaScripta. Preuzimanje XML podataka

San zbog kojeg je Web stvoren je uobičajen informativni prostor u kojoj komuniciramo dijeljenjem informacija. Njegova svestranost je sastavni dio: hipertekstualna veza može voditi bilo gdje, bilo da se radi o ličnim, lokalnim ili globalnim informacijama, nacrtu ili revidiranom tekstu.

Tim Bernes-Lee, World Wide Web: Vrlo kratka lična istorija

Protokol

Ako upišete eloquentjavascript.net/17_http.html u adresnu traku vašeg pretraživača, pretraživač prvo prepoznaje adresu servera povezanu sa imenom eloquentjavascript.net i pokušava da otvori TCP veza na portu 80 - podrazumevani port za HTTP. Ako server postoji i prihvata vezu, pretraživač šalje nešto poput:

GET /17_http.html HTTP / 1.1
Domaćin: eloquentjavascript.net
Korisnički agent: Ime pretraživača

Server odgovara preko iste veze:

HTTP / 1.1 200 OK
Dužina sadržaja: 65585
Content-Type: text / html


... ostatak dokumenta

Pregledač preuzima dio koji slijedi nakon odgovora prazan red i prikazuje ga kao HTML dokument.

Informacija koju šalje klijent naziva se zahtjev. Počinje sa linijom:

GET /17_http.html HTTP / 1.1

Prva riječ je metoda zahtjeva. GET znači da trebamo dobiti određeni resurs. Druge uobičajene metode su DELETE za brisanje, PUT za zamjenu i POST za slanje informacija. Imajte na umu da server nije dužan ispuniti svaki zahtjev koji primi. Ako odaberete nasumično mjesto i kažete mu IZBRIŠI početna stranica- najverovatnije će odbiti.

Dio iza naziva metode je putanja do resursa na koji je zahtjev poslan. U najjednostavnijem slučaju, resurs je samo datoteka na serveru, ali protokol nije ograničen na ovu mogućnost. Resurs može biti bilo šta što se može proslijediti kao datoteka. Mnogi serveri kreiraju odgovore u hodu. Na primjer, ako otvorite twitter.com/marijnjh, server će potražiti korisnika marijnjh u bazi podataka, a ako ga pronađe, kreirat će stranicu profila za tog korisnika.

Nakon putanje resursa, u prvom redu zahtjeva se spominje HTTP / 1.1 kako bi se naznačila verzija HTTP protokola koji koristi.

Odgovor servera također počinje s verzijom protokola nakon čega slijedi status odgovora - prvo kod od tri cifre, zatim linija.

HTTP / 1.1 200 OK

Statusni kodovi koji počinju sa 2 označavaju uspješne zahtjeve. Kodovi koji počinju sa 4 znače da je nešto pošlo po zlu. 404 je najpoznatiji HTTP status, koji ukazuje da traženi resurs nije pronađen. Kodovi koji počinju sa 5 označavaju da je došlo do greške na serveru, ali ne zbog zahtjeva.

Prvi red zahtjeva ili odgovora može biti praćen bilo kojim brojem redova zaglavlja. Ovo su nazivni nizovi vrijednosti koji predstavljaju Dodatne informacije o zahtjevu ili odgovoru. Ova zaglavlja su uključena u primjer:

Dužina sadržaja: 65585
Content-Type: text / html
Zadnja izmjena: Wed, 09 Apr 2014 10:48:09 GMT

Ovo određuje veličinu i vrstu dokumenta primljenog kao odgovor. V u ovom slučaju to je 65'585 bajt HTML dokument. Također označava kada je dokument posljednji put izmijenjen.

Uglavnom, klijent ili server određuju koja zaglavlja treba uključiti u zahtjev ili odgovor, iako su neka zaglavlja potrebna. Na primjer, Host, koji označava ime hosta, treba biti uključen u zahtjev, jer jedan server može poslužiti više imena hosta na jednoj ip-adresi, a bez ovog zaglavlja server neće znati s kojim hostom klijent pokušava komunicirati.

Nakon zaglavlja, i zahtjev i odgovor mogu specificirati prazan niz, nakon čega slijedi tijelo koje sadrži podatke koji se prenose. Zahtjevi GET i DELETE ne šalju dodatne podatke, ali PUT i POST šalju. Neki odgovori, kao što su poruke o grešci, ne zahtijevaju tijelo.

Pretraživač i HTTP

Kao što smo vidjeli u primjeru, pretraživač postavlja zahtjev kada unesemo URL u adresna traka... Kada je primljen HTML dokument sadrži reference na druge datoteke, kao što su slike ili JavaScript datoteke, oni se također traže od servera.

Prosječna web stranica može lako sadržavati 10 do 200 resursa. Da bi ih mogli zatražiti brže, pretraživači upućuju više zahtjeva u isto vrijeme, umjesto da čekaju da se zahtjevi završe jedan po jedan. Takvi dokumenti se uvijek traže putem GET zahtjeva.

Na HTML stranice mogu postojati obrasci koji omogućavaju korisnicima da unesu informacije i predaju ih serveru. Evo primjera obrasca:

ime:

Poruka:

Kod opisuje obrazac sa dva polja: malo traži ime, a veliko za poruku. Kada kliknete na dugme "Pošalji", informacije iz ovih polja će biti kodirane u niz upita. Kada je atribut metode elementa GET, ili kada uopće nije specificiran, string upita se stavlja u URL iz polja akcije, a pretraživač pravi GET zahtjev sa tim URL-om.

GET /example/message.html?name=Jean&message=Da%3F HTTP / 1.1

Početak niza upita je označen znakom pitanja. Nakon toga slijede parovi imena i vrijednosti koje odgovaraju atribut imena polja obrasca i sadržaj tih polja. Ampersand (&) se koristi za njihovo razdvajanje.

Poruka poslana u primjeru sadrži string “Da?”, iako je upitnik zamijenjen nekim čudnim kodom. Neki znakovi u stringu upita moraju biti prikazani. Znak pitanja takođe, a predstavljen je kodom% 3F. Postoji neko nepisano pravilo da svaki format mora imati način za izbjegavanje znakova. Ovo pravilo se zove url kodiranje koristi postotak nakon kojeg slijede dvije heksadecimalne cifre za predstavljanje koda znakova. 3F decimala bi bila 63, što je kod znaka pitanja. JavaScript ima funkcije encodeURIComponent i decodeURIComponent za kodiranje i dekodiranje.

Console.log (encodeURIComponent ("Zdravo i zbogom")); // → Zdravo% 20% 26% 20goodbye console.log (decodeURIComponent ("Hello% 20% 26% 20goodbye")); // → Zdravo i doviđenja

Ako promijenimo atribut metode na obrascu u prethodnom primjeru u POST, HTTP zahtjev podnošenje obrasca će biti završeno sa POST metoda koji će poslati string upita u tijelu zahtjeva umjesto da ga doda URL-u.

POST /example/message.html HTTP / 1.1
Dužina sadržaja: 24
Vrsta sadržaja: aplikacija / x-www-form-urlencoded

Ime = Jean & poruka = ​​Da% 3F

Po dogovoru GET metoda koristi se za upite koji nemaju nuspojave, kao što su pretrage. Kreiraju se zahtjevi koji mijenjaju nešto na serveru novi račun ili objavite poruku, mora se poslati metodom POST. Klijentski programi poput pretraživača, znaju da nije potrebno samo tako praviti POST zahtjeve, a ponekad i GET zahtjeve prave neprimijećeno od strane korisnika - na primjer, da unaprijed preuzmu sadržaj koji bi korisniku mogao uskoro zatrebati.

U sljedećem poglavlju vratit ćemo se na obrasce i razgovarati o tome kako ih možemo napraviti pomoću JavaScripta.

XMLHttpRequest

Interfejs preko kojeg JavaScript u pretraživaču može postavljati HTTP zahtjeve naziva se XMLHttpRequest (primijetite kako veličine slova skaču). Razvio ga je Microsoft za pretraživač Internet Explorer kasnih 1990-ih. U to vrijeme XML format je bio veoma popularan u svetu poslovnog softvera - i u ovom svetu Microsoft se uvek osećao kao kod kuće. Bio je toliko popularan da je akronim XML zakačen ispred interfejsa za rad sa HTTP-om, iako ovaj drugi uopšte nije povezan sa XML-om.

Ipak, ime nije potpuno besmisleno. Interfejs vam omogućava da raščlanite odgovore kao da su XML dokumenti. Miješanje dvije različite stvari (parsing zahtjeva i odgovora) u jednu je, naravno, odvratan dizajn, ali šta možete učiniti.

Kada je interfejs XMLHttpRequest dodat u Internet Explorer, postalo je moguće raditi stvari koje su ranije bile veoma teške. Na primjer, web stranice su počele prikazivati ​​liste opisa alata dok korisnik upisuje nešto u tekstualno polje. Skripta šalje tekst serveru preko HTTP-a u isto vrijeme kada korisnik kuca. Server koji ima bazu podataka za moguće opcije input, traži među unosima one koji se podudaraju i vraća ih nazad za prikaz. Izgledalo je vrlo cool – ljudi su čekali da se cijela stranica ponovo učita nakon svake interakcije s web-mjestom.

Drugi važan pretraživač Mozilla (kasnije Firefox) nije želela da zaostaje. Da bi omogućila slične stvari, Mozilla je kopirala sučelje zajedno s imenom. Sljedeća generacija pretraživača slijedila je primjer, a danas je XMLHttpRequest de facto standard.

Slanje zahtjeva

Da bismo poslali jednostavan zahtjev, kreiramo objekt zahtjeva sa konstruktorom XMLHttpRequest i pozivamo metode open i send.

Var req = novi XMLHttpRequest (); req.open ("GET", "example / data.txt", false); req.send (null); console.log (req.responseText); // → Ovo je sadržaj data.txt

Otvorena metoda postavlja zahtjev. U našem slučaju, odlučili smo napraviti GET zahtjev za datoteku example /data.txt. URL-ovi koji ne počinju imenom protokola (na primjer, http :) nazivaju se relativnim, odnosno interpretiraju se relativno aktuelni dokument... Kada počnu sa kosom crtom (/), zamjenjuju trenutnu putanju - dio iza imena servera. Inače, dio trenutni put do zadnje kose crte se stavlja ispred relativnog URL-a.

Nakon otvaranja zahtjeva, možemo ga poslati metodom slanja. Argument je tijelo zahtjeva. Za GET zahtjeve koristi se null. Ako je treći argument za otvaranje bio netačan, send će se vratiti tek nakon što se primi odgovor na naš zahtjev. Da bismo dobili tijelo odgovora, možemo pročitati svojstvo responseText objekta zahtjeva.

Možete dobiti i druge informacije od objekta odgovora. Statusni kod je dostupan u svojstvu statusa, a tekst statusa je dostupan u statusText. Zaglavlja se mogu pročitati iz getResponseHeader.

Var req = novi XMLHttpRequest (); req.open ("GET", "example / data.txt", false); req.send (null); console.log (req.status, req.statusText); // → 200 OK console.log (req.getResponseHeader ("content-type")); // → tekst / običan

Imena zaglavlja ne razlikuju velika i mala slova. Obično se pišu sa veliko slovo na početku svake riječi, na primjer “Content-Type”, ali “content-type” ili “conTeNt-TyPe” će opisati isti naslov.

Pregledač će sam dodati neka zaglavlja, kao što su "Host" i druga, koja su serveru potrebna da izračuna veličinu tijela. Ali možete dodati vlastita zaglavlja metodom setRequestHeader. Ovo je potrebno za posebnim slučajevima i zahtijeva pomoć servera kojem pristupate - slobodno je zanemariti zaglavlja s kojima ne može rukovati.

Asinhroni zahtjevi

U primjeru, zahtjev je završen kada se završi poziv za slanje. Ovo je zgodno jer su svojstva kao što je responseText odmah dostupna. Ali to znači da će naš program čekati dok pretraživač i server međusobno komuniciraju. At loša konekcija, slab server, ili veliki fajl ovo može potrajati dugo vrijeme... Ovo je također loše jer se neće pokrenuti rukovatelji događaja dok je program u stanju pripravnosti - dokument će prestati reagirati na radnje korisnika.

Ako predamo true kao treći argument za otvaranje, zahtjev će biti asinhroni. To znači da kada pozovete send, zahtjev se stavlja u red čekanja za slanje. Program nastavlja da radi, a pretraživač se brine o slanju i primanju podataka u pozadini.

Ali dok se zahtjev obrađuje, nećemo dobiti odgovor. Potreban nam je mehanizam za obavještavanje da su podaci stigli i spremni. Da bismo to učinili, morat ćemo poslušati događaj “load”.

Var req = novi XMLHttpRequest (); req.open ("GET", "example / data.txt", istina); req.addEventListener ("učitavanje", funkcija () (console.log ("Gotovo:", req.status);)); req.send (null);

Baš kao i poziv requestAnimationFrame u poglavlju 15, ovaj kod nas prisiljava da koristimo stil asinhronog programiranja tako što umotavamo kod koji treba da se izvrši nakon zahtjeva u funkciju i organizuje poziv ove funkcije u pravo vrijeme... Na ovo ćemo se vratiti kasnije.

Preuzimanje XML podataka

Kada je resurs koji vraća XMLHttpRequest objekt XML dokument, svojstvo responseXML će sadržavati raščlanjeni prikaz dokumenta. Radi na sličan način kao DOM, osim što mu nedostaje inherentna funkcionalnost HTML-a kao što je svojstvo stila. Objekt sadržan u responseXML-u odgovara objektu dokumenta. Njegovo svojstvo documentElement odnosi se na eksternu oznaku XML dokumenta. V sljedeći dokument(primjer / fruit.xml) ova oznaka bi bila:

Možemo dobiti ovakav fajl:

Var req = novi XMLHttpRequest (); req.open ("GET", "example / fruit.xml", false); req.send (null); console.log (req.responseXML.querySelectorAll ("voće"). dužina); // → 3

XML dokumenti se mogu koristiti za razmjenu sa serverom strukturirane informacije... Njihov oblik - ugniježđene oznake - vrlo je prikladan za pohranjivanje većine podataka, dobro ili po najmanje bolje nego tekstualne datoteke... DOM sučelje je nezgodno u smislu preuzimanja informacija, i XML dokumenti prilično su opsežni. Obično je najbolje komunicirati koristeći JSON podatke, koje je lakše čitati i pisati, i za programe i za ljude.

Var req = novi XMLHttpRequest (); req.open ("GET", "example / fruit.json", false); req.send (null); console.log (JSON.parse (req.responseText)); // → (banana: "žuta", limun: "žuta", trešnja: "crvena")

Sandbox za HTTP

HTTP zahtjevi sa web stranice izazivaju zabrinutost za sigurnost. Osoba koja kontroliše skriptu može imati interese drugačije od interesa korisnika na čijem računaru se ona izvodi. Konkretno, ako odem na themafia.org, ne želim da njihove skripte mogu da postavljaju upite mybank.com koristeći podatke mog pretraživača kao identifikator, i da me upute da pošaljem sav svoj novac na neki mafijaški račun.

Web stranice se mogu odbraniti od ovakvih napada, ali je potrebno malo truda i mnoge web stranice ne uspijevaju se nositi s tim. Zbog toga ih pretraživači štite sprečavanjem skripti da upućuju zahtjeve drugim domenima (nazivima poput themafia.org i mybank.com).

Ovo može ometati razvoj sistema kojima je potreban pristup različite domene sa dobrim razlogom. Na sreću, server može uključiti sljedeće zaglavlje u odgovor, govoreći pretraživačima da zahtjev može doći s drugih domena:

Access-Control-Allow-Origin: *

Apstrahovanje zahteva

Poglavlje 10 u našoj implementaciji modularni sistem AMD-u smo koristili hipotetičku funkciju backgroundReadFile. Uzeo je ime datoteke i funkciju i pozvao tu funkciju nakon čitanja sadržaja datoteke. Evo jednostavna implementacija ova funkcija:

Funkcija backgroundReadFile (url, callback) (var req = novi XMLHttpRequest (); req.open ("GET", url, true); req.addEventListener ("load", funkcija () (if (req.status< 400) callback(req.responseText); }); req.send(null); }

Jednostavna apstrakcija olakšava korištenje XMLHttpRequest za jednostavne GET zahtjeve. Ako pišete program koji postavlja HTTP zahtjeve, dobra je ideja koristiti pomoćnu funkciju kako ne biste morali stalno ponavljati ružni obrazac XMLHttpRequest.

Argument povratnog poziva je termin koji se često koristi za opisivanje takvih funkcija. Funkcija povratnog poziva se prosljeđuje drugom kodu kako bi nas kasnije mogao pozvati.

Nije teško napisati sopstvenu HTTP pomoćnu funkciju skrojenu posebno za vaš program. Prethodni samo postavlja GET zahtjeve i ne daje nam kontrolu nad zaglavljima ili tijelom zahtjeva. Možete napisati drugu varijantu za POST zahtjev, ili općenitiju koja podržava različite zahtjeve. Mnoge JavaScript biblioteke nude omote za XMLHttpRequest.

Glavni problem sa gornjim omotom je rukovanje greškama. Kada zahtjev vrati statusni kod greške (400 ili veći), ne radi ništa. Ovo je u redu u nekim slučajevima, ali zamislite da na stranicu stavimo indikator učitavanja koji pokazuje da primamo informacije. Ako zahtjev ne uspije jer je server pao ili je veza prekinuta, stranica će se pretvarati da je zauzeta nečim. Korisnik će malo pričekati, a onda će mu dosaditi i odlučit će da je stranica nekakva glupa.

Potrebna nam je opcija u kojoj dobijamo upozorenje o neuspjelom zahtjevu kako bismo mogli nešto poduzeti. Na primjer, možemo ukloniti poruku za preuzimanje i obavijestiti korisnika da je nešto pošlo po zlu.

Rukovanje greškama u asinkronom kodu je još teže nego u sinkronom kodu. Budući da često moramo odvojiti dio posla i smjestiti ga u funkciju povratnog poziva, opseg bloka try je besmislen. U sljedećem kodu izuzetak neće biti uhvaćen jer se poziv backgroundReadFile vraća odmah. Tada kontrola napušta try blok, a funkcija iz nje neće biti pozvana.

Pokušajte (backgroundReadFile ("example / data.txt", funkcija (tekst) (if (text! = "Očekivano") izbaciti novu grešku ("To je bilo neočekivano");));) catch (e) (console.log ( "Zdravo iz bloka za hvatanje");)

Za obradu neuspješnih zahtjeva, morat ćete poslati dodatna funkcija u naš omot i pozovite ga u slučaju problema. Druga opcija je korištenje konvencije da ako zahtjev ne uspije, dodatni argument se prosljeđuje funkciji povratnog poziva koja opisuje problem. primjer:

Funkcija getURL (url, callback) (var req = novi XMLHttpRequest (); req.open ("GET", url, true); req.addEventListener ("load", funkcija () (if (req.status< 400) callback(req.responseText); else callback(null, new Error("Request failed: " + req.statusText)); }); req.addEventListener("error", function() { callback(null, new Error("Network error")); }); req.send(null); }

Kod koji koristi getURL treba provjeriti da li je vraćena greška i obraditi je ako postoji.

GetURL ("podaci / nonsense.txt", funkcija (sadržaj, greška) (ako (greška! = Null) console.log ("Neuspjelo dohvatiti nonsense.txt:" + greška); inače console.log ("nonsense.txt : "+ sadržaj);));

Ne pomaže kod izuzetaka. Kada izvršimo nekoliko uzastopnih asinhronih radnji, izuzetak u bilo kojoj tački lanca u svakom slučaju (osim ako ne omotate svaki rukovalac u svoj vlastiti blok try/catch) će ispasti na najvišem nivou i prekinuti cijeli lanac.

Obećanja

Teško je napisati asinhroni kod složenih projekata u obliku jednostavnog povratni pozivi... Vrlo je lako zaboraviti provjeriti ima li greške ili dozvoliti neočekivanom izuzetku da naglo prekine vaš program. Osim toga, organizacija ispravna obrada greške i prenošenje greške kroz više uzastopnih povratnih poziva je veoma zamorno.

Bilo je mnogo pokušaja da se ovaj problem riješi dodatnim apstrakcijama. Jedan od uspješnijih pokušaja se zove obećanja. Obećanja omotavaju asinkronu akciju u objekt koji se može proslijediti i koji treba nešto učiniti kada se akcija završi ili ne uspije. Takav interfejs je već postao deo sadašnjeg JavaScript verzije a za starije verzije može se koristiti kao biblioteka.

Interfejs obećanja nije posebno intuitivan, ali moćan. U ovom poglavlju ćemo ga samo djelimično opisati. Više informacija možete pronaći na www.promisejs.org

Da bismo kreirali objekat obećanja, pozivamo konstruktor Promise, dajući mu asinkronu funkciju inicijalizacije akcije. Konstruktor poziva ovu funkciju i prosljeđuje joj dva argumenta, koji su i sami funkcije. Prvi treba pozvati u uspješnom slučaju, drugi u neuspješnom.

A evo našeg omotača za GET zahtjeve, koji ovaj put vraća obećanje. Sada ćemo to nazvati dobiti.

Funkcija get (url) (vraća novo obećanje (funkcija (uspjeh, neuspjeh) (var req = novi XMLHttpRequest (); req.open ("GET", url, true); req.addEventListener) ("učitavanje", funkcija) () ( if (req.status< 400) succeed(req.responseText); else fail(new Error("Request failed: " + req.statusText)); }); req.addEventListener("error", function() { fail(new Error("Network error")); }); req.send(null); }); }

Imajte na umu da je sučelje za samu funkciju pojednostavljeno. Prosljeđujemo joj URL i ona vraća obećanje. Djeluje kao rukovalac za izlaz zahtjeva. Ima tada metod koji se poziva s dvije funkcije, jednom za rješavanje uspjeha, a drugom za rješavanje neuspjeha.

Get ("example / data.txt"). Zatim (funkcija (tekst) (console.log ("data.txt:" + tekst);), funkcija (greška) (console.log ("Neuspjelo dohvaćanje data.txt : "+ greška);));

Iako je ovo još uvijek jedan od načina da izrazimo ono što smo već uradili. Tek kada imate niz događaja, vidite primjetnu razliku.

Pozivanje tada proizvodi novo obećanje čiji rezultat (vrijednost proslijeđena rukovaocima uspjeha) ovisi o povratnoj vrijednosti prve funkcije kojoj smo tada proslijedili. Ova funkcija može vratiti još jedno obećanje, što ukazuje da se obavlja dodatni asinhroni rad. U ovom slučaju, obećanje koje je tada vraćeno samo će čekati na obećanje koje je vratila funkcija rukovatelja, a uspjeh ili neuspjeh će se dogoditi s istom vrijednošću. Kada funkcija rukovatelja vrati vrijednost koja nije obećana, obećanje koje je tada vraćeno uspijeva korištenjem te vrijednosti kao rezultat.

To znači da onda možete koristiti za promjenu rezultata obećanja. Na primjer, sljedeća funkcija vraća obećanje čiji je rezultat sadržaj datog URL-a raščlanjen kao JSON:

Funkcija getJSON (url) (return get (url) .then (JSON.parse);)

Poslednji poziv tada nije odredio rukovaoca greškama. Ovo je dozvoljeno. Greška će biti proslijeđena obećanju koje je tada vraćeno, a ovo je ono što nam treba - getJSON ne zna šta da radi kada nešto krene po zlu, ali postoji nada da pozivni kod to zna.

Kao primjer koji pokazuje upotrebu obećanja, napisaćemo program koji prima određeni broj JSON datoteka sa servera i prikazuje riječ “download” tokom izvršavanja zahtjeva. Datoteke sadrže informacije o ljudima i veze do drugih datoteka s informacijama o drugim osobama u posjedima kao što su otac, majka, supružnik.

Trebamo dobiti ime majke supružnika iz primjera / bert.json. U slučaju problema, moramo ukloniti tekst "učitavanja" i prikazati poruku o grešci. Evo kako to možete učiniti uz obećanja:

Rezultirajući program je relativno kompaktan i čitljiv. Metoda catch je slična tada, ali očekuje samo neuspješan obrađivač rezultata i, ako je uspješan, prosljeđuje nepromijenjeni rezultat. Izvršavanje programa će se nastaviti na uobičajen način nakon hvatanja izuzetka - baš kao u slučaju pokušaja/hvatanja. Dakle, final then, koji uklanja poruku o učitavanju, se svejedno izvršava, čak i ako ne uspije.

Možete zamisliti interfejs obećanja kao poseban jezik za asinhrono rukovanje izvršavanjem programa. Dodatni pozivi metodama i funkcijama koji su potrebni da bi on funkcionirao čine da kod izgleda malo čudno, ali ne tako nezgodno kao rukovanje svim greškama.

Cijeni HTTP

Prilikom kreiranja sistema u kojem JavaScript program u pretraživaču (na strani klijenta) komunicira sa serverski program, možete koristiti nekoliko opcija za modeliranje takve komunikacije.

Uobičajena tehnika su pozivi udaljenih procedura. U ovom modelu komunikacija slijedi obrazac običnih poziva funkcija, samo se te funkcije izvode na drugom računalu. Poziv je kreiranje zahtjeva za server, koji uključuje ime funkcije i argumente. Odgovor na zahtjev uključuje povratnu vrijednost.

Kada koristite udaljene pozive procedura, HTTP služi samo kao transport za komunikaciju, a vi ćete najvjerovatnije napisati sloj apstrakcije koji ga potpuno skriva.

Drugi pristup je da izgradite svoj komunikacioni sistem oko koncepta HTTP resursa i metoda. Umjesto poziva udaljene procedure koja se zove addUser, vi to činite PUT zahtjev za / korisnike / larry. Umjesto kodiranja prilagođenih svojstava u argumentima funkcije, vi definirate format dokumenta ili korištenje postojeći format koji će predstavljati korisnika. Tijelo izrade PUT zahtjeva novi resurs, jednostavno će biti dokument ovog formata. Resurs se dobija putem GET zahtjeva na njegov URL (/user/larry), koji vraća dokument koji predstavlja resurs.

Drugi pristup olakšava korištenje nekih HTTP mogućnosti, na primjer, podrška za keširanje resursa (kopija resursa je pohranjena na strani klijenta). Takođe pomaže u stvaranju konzistentnog interfejsa jer je lakše razmišljati u smislu resursa nego u smislu funkcija.

Sigurnost i HTTPS

Podaci putuju internetom duž dugog i opasnog puta. Da bi došli do svog odredišta, moraju preskočiti razna mjesta, počevši od Wi-Fi mreže od kafića do lanaca pod kontrolom različite organizacije i države. U svakom trenutku na putu, mogu se pročitati ili čak promijeniti.

Ako nešto treba da čuvate u tajnosti, kao što su lozinke e-pošte, ili podaci moraju stići na odredište nepromijenjeni, kao što je broj bankovnog računa na koji prenosite novac, jednostavan HTTP nije dovoljan.

Sigurni HTTP protokol, čiji URL-ovi počinju s https: //, obavija HTTP promet na način koji je teže čitati i mijenjati. Klijent prvo potvrđuje da je server ono za koga tvrdi da je tako što zahtijeva od servera da predstavi kriptografski certifikat izdat od strane ovlaštene strane koju pretraživač prepoznaje. Zatim se svi podaci koji prolaze kroz vezu šifriraju kako bi se spriječilo prisluškivanje i izmjena.

Na ovaj način, kada sve radi kako treba, HTTPS sprečava kako slučajeve kada se neko pretvara da je drugi sajt sa kojim komunicirate, tako i slučajeve prisluškivanja vaše komunikacije. Nije savršeno, a već je bilo slučajeva da HTTPS nije uspio zbog lažnih ili ukradenih certifikata ili pokvarenih programa. Međutim, vrlo je lako učiniti nešto loše s HTTP-om, a razbijanje HTTPS-a zahtijeva vrstu napora koji mogu uložiti samo vladine agencije ili vrlo ozbiljne kriminalne organizacije (i ponekad nema razlike između ovih organizacija).

Ishod

U ovom poglavlju smo vidjeli da je HTTP protokol za pristup resursima na Internetu. Klijent šalje zahtjev koji sadrži metodu (obično GET) i putanju koja identificira resurs. Server odlučuje šta će učiniti sa zahtjevom i odgovara sa statusnim kodom i tijelom odgovora. Zahtjevi i odgovori mogu sadržavati zaglavlja koja prenose dodatne informacije.

Pretraživači postavljaju GET zahtjeve kako bi dobili resurse potrebne za prikazivanje stranice. Stranica može sadržavati obrasce koji omogućavaju da se informacije koje je korisnik unio u zahtjev koji se generira nakon podnošenja obrasca. Više o tome saznat ćete u sljedećem poglavlju.

Interfejs preko kojeg JavaScript šalje HTTP zahtjeve iz pretraživača naziva se XMLHttpRequest. Možete zanemariti "XML" prefiks (ali ga i dalje morate napisati). Može se koristiti na dva načina: sinhroni, koji blokiraju sav rad do kraja zahtjeva, i asinhroni, koji zahtijevaju instalaciju rukovatelja događajima za praćenje kraja zahtjeva. U gotovo svim slučajevima, poželjno je asinhroni način... Kreiranje zahtjeva izgleda ovako:

Var req = novi XMLHttpRequest (); req.open ("GET", "example / data.txt", istina); req.addEventListener ("učitavanje", funkcija () (console.log (req.statusCode);)); req.send (null);

Asinhrono programiranje je nezgodno. Obećanja su interfejs koji ga čini jednostavnijim tako što pomaže da se poruke o grešci i izuzeci usmere do ispravnog rukovaoca i apstrahujući neke elemente koji se ponavljaju, skloni greškama.

Vježbe

Pregovaranje o sadržaju
Jedna od stvari koje HTTP može učiniti, a o kojoj nismo razgovarali, zove se pregovaranje o sadržaju. Zaglavlje Accept u zahtjevu može se koristiti da kaže serveru koje vrste dokumenata klijent želi primiti. Mnogi serveri to ignorišu, ali kada server zna za različite načine kodiranja resursa, može pogledati zaglavlje i poslati ono koje klijent preferira.

eloquentjavascript.net/author URL je konfigurisan da odgovori u običnom tekstu i HTML ili JSON u zavisnosti od zahteva klijenta. Ovi formati su definisani standardizovanim tipovima sadržaja text / plain, text / html i application / json.

Pošaljite zahtjev za primanje sva tri formata za ovaj resurs. Koristite metodu setRequestHeader objekta XMLHttpRequest da postavite zaglavlje Accept na jedno od potrebne vrste sadržaja. Obavezno postavite zaglavlje nakon otvaranja, ali prije slanja.

Na kraju, pokušajte zatražiti sadržaj kao što je aplikacija / duge + jednorozi i pogledajte što će se dogoditi.

Čeka se više obećanja
Konstruktor Promise ima all metod koji, kada primi niz obećanja, vraća obećanje koje čeka da se sva obećanja navedena u nizu dovrše. Zatim izdaje uspješan rezultat i vraća niz s rezultatima. Ako bilo koje od obećanja u nizu ne uspije, zajedničko obećanje također ne uspijeva (sa vrijednošću neuspjelog obećanja iz niza).

Probajte ovako nešto tako što ćete napisati funkciju all.

Imajte na umu da jednom kada je obećanje dovršeno (kada ili uspije ili ne uspije), ne može ponovno izbaciti grešku ili uspjeh, a daljnji pozivi funkcija se zanemaruju. Ovo može olakšati rukovanje greškama u vašem obećanju.

Funkcija sve (obećanja) (vrati novo obećanje (funkcija (uspjeh, neuspjeh) (// Vaš kod.));) // Verifikacijski kod. all (). then (funkcija (niz) (console.log ("Ovo bi trebalo biti:", niz);)); funkcija uskoro (val) (vrati novo obećanje (funkcija (uspjeh) (setTimeout (funkcija () (uspjeh (val);), Math.random () * 500);));) sve (). zatim (funkcija (niz ) (console.log ("Ovo bi trebalo biti:", niz;)); funkcija neuspjeh () (vrati novo obećanje (funkcija (uspjeh, neuspjeh) (neuspjeh (nova greška ("bang"));));) sve (). zatim (funkcija (niz) (console.log ("Dolazimo ovdje ne bi trebalo ");), funkcija (greška) (if (error.message! =" bang ") console.log (" Neočekivana nevolja: ", greška);));

Već duže vrijeme mnoge stranice imaju dinamičke stranice, odnosno ažuriraju se bez ponovnog pokretanja. Ovo se postiže pomoću pozivi servera putem JavaScripta, u većini slučajeva jeste POST i GET zahtjevi... I skoro uvijek se takve stranice koriste za to Ajax... I ne znaju svi (nažalost) to Ajax nije poseban jezik, već samo JavaScript biblioteka... zaključak: Ajax je pravedan zgodan način poslati POST zahtjeve, ali sve se to može uraditi i bez njegove pomoći. Evo kako poslati POST zahtjeve putem JavaScripta bez Ajaxa, objasnit ću u ovom članku.

Sada ćemo riješiti klasični problem - ovo je zbir dva broja koje odredi korisnik. Odnosno, računamo od tekstualnih polja 2 brojeve, pošaljite ih na server, dobijete odgovor i prikažite ih na stranici. I sve ovo bez ponovnog učitavanja stranice.

Počnimo jednostavno: pisanje PHP kod:

$ a = $ _POST ["a"];
$ b = $ _POST ["b"];
echo $ a + $ b;
?>

Ovdje je sve elementarno, pa neću ni komentarisati. A sada je teži dio strana klijenta:










Zbir je jednak:


Html kod Neću komentarisati jer je potpuno transparentno. Ali da JavaScript Dodaću malo, uprkos detaljnim komentarima. Prvo, funkcija getXmlHttp () je svestran. Možete ga sigurno kopirati u svoje skripte. Njen zadatak je vratiti takve XMLHTTP da radi u bilo kom pretraživaču. Zato što je najpopularnija opcija novi XMLHttpRequest () međutim ne radi, na primjer u IE6... Druge opcije takođe nisu univerzalne, tako da ovde samo biramo radnu opciju za bilo koji pretraživač.

Takođe sam pisao u komentarima o " asinhroni rad ". Postoji i sinhrona opcija. Jedina razlika je u tome sinhrono dok se ne primi odgovor od servera, pretraživač neće raditi, samo visi. Teško mi je da smislim takav zadatak tamo gde je to potrebno, pa sam odmah napisao asinhrona opcija... Radi na sljedeći način: mi šaljemo zahtjev i čekamo odgovor, ali pretraživač ne visi... A kada dođe odgovor ( xmlhttp.readyState == 4), tada odmah obrađujemo odgovor. Ovo je asinhrona verzija rada, malo je složenija, ali samo nju treba koristiti (s izuzetkom vrlo rijetkih slučajeva).

Na ovaj način POST zahtjevi se šalju putem JavaScripta... Kao što možete vidjeti Ajax nije nam uopšte trebao. I toplo preporučujem da ako imate samo nekoliko zahtjeva za cijelu stranicu, onda ni ne razmišljate o korištenju ove glomazne biblioteke, već koristite materijal ovog članka.

Lekcija u kojoj ćemo koristiti primjere za kreiranje jednostavnih asinkronih AJAX zahtjeva za server. Koristit ćemo i GET metodu i POST metodu kao metodu za prijenos zahtjeva. Na serveru ćemo obraditi zahtjeve koristeći PHP skripte.

Šta je asinhroni AJAX zahtjev?

AJAX tehnologija se uglavnom koristi za izradu asinhronih zahtjeva prema serveru. Asinhroni zahtjev je takav zahtjev koji se izvršava u pozadini i ne sprječava korisnika u interakciji sa stranicom.

Prilikom slanja asinhronog zahtjeva, pretraživač (stranica) nije "zamrznut", tj. sa njom, kao i ranije, možete raditi. Ali kako onda znati kada će doći odgovor sa servera. Da biste to utvrdili, morate pratiti svojstvo readyState pretraživača. Ova nekretnina sadrži broj, po čijoj vrijednosti možete prosuditi u kojoj je fazi zahtjev. Sljedeća tabela sažima osnovne vrijednosti svojstva readyState i njihova odgovarajuća stanja.

One. ispostavilo se da moramo pratiti kada je vrijednost svojstva readyState jednaka 4. To će značiti da je poslani zahtjev dobio odgovor od servera. Ostale vrijednosti se rijetko koriste u praksi, a neki pretraživači ih možda ne podržavaju.

Da biste odredili u kojoj se fazi nalazi zahtjev, trebate koristiti događaj onreadystatechange objekta XMLHttpRequest. Ovaj događaj javlja se svaki put kada se promijeni vrijednost svojstva readyState. Stoga, u rukovatelju ovog događaja (neimenovane ili imenovane funkcije), možete napisati akcije koje će provjeriti da li je ovo svojstvo jednako 4 i, ako jeste, na primjer, prikazati odgovor servera na stranici.

Izrada asinhronog AJAX zahtjeva (GET metoda)

Razmislite o kreiranju asinhronog AJAX zahtjev na primjer koji će, nakon učitavanja stranice, pozdraviti korisnika i prikazati njegovu IP adresu.

Da biste to učinili, morate kreirati 2 datoteke na serveru u jednom direktoriju:

  1. welcome.html - HTML stranica koja će biti prikazana korisniku. Na istoj stranici ćemo postaviti skriptu koja će sve izvršiti neophodne radnje za AJAX rad na strani klijenta.
  2. Processing.php - PHP datoteka koja će obraditi zahtjev na strani servera i formirati odgovor. Započnimo razvoj kreiranjem osnovne strukture datoteke welcome.html.
Primjer rada AJAX-a

Primjer rada AJAX-a

Pogledajmo redoslijed radnji koje treba izvršiti na strani klijenta (u JavaScript kodu):

    Pripremimo podatke potrebne za izvršavanje zahtjeva na serveru. Ako za izvršenje upita na serveru nisu potrebni podaci, onda se ova faza može preskočiti.

    Kreirajmo varijablu koja će sadržavati instancu XHR objekta (XMLHttpRequest).

    Konfigurirajmo zahtjev koristeći open () metodu.

    Navedeni su sljedeći parametri:

    • Metoda kojom će se zahtjev poslati na server (GET, POST).
    • URL koji će obraditi zahtjev na serveru.
    • Vrsta zahtjeva: sinhroni (lažno) ili asinhroni (tačno).
    • Korisničko ime i lozinka ako je potrebno.
  1. Pretplatite se na događaj onreadystatechange XHR objekta i navedite rukovaoca kao anonimnu ili imenovanu funkciju. Nakon toga ćemo kreirati kod unutar ove funkcije koji će provjeriti status odgovora i izvršiti određene radnje na stranici. Odgovor koji dolazi od servera je uvijek u svojstvu responseText.

    Osim provjere vrijednosti svojstva readyState brojem 4, možete provjeriti vrijednost svojstva statusa. Ovo svojstvo određuje status zahtjeva. Ako je 200, onda je sve u redu. U suprotnom, došlo je do greške (na primjer, 404 - URL nije pronađen).

    Pošaljimo zahtjev serveru pomoću metode send ().

    Ako koristimo metodu GET za slanje zahtjeva, onda prosljeđujemo podatke u parametar ovu metodu nema potrebe. Oni se prosljeđuju kao dio URL-a.

    Ako koristimo POST metodu za slanje zahtjeva, tada podaci moraju biti proslijeđeni kao parametar metodi send (). Osim toga, prije pozivanja ove metode, morate postaviti zaglavlje Content-Type tako da server zna u kojem kodiranju mu je zahtjev stigao i da ga može dešifrirati.

Sadržaj elementa skripte:

// 2. Kreirajte varijabilni zahtjev var request = new XMLHttpRequest (); // 3. Postavljanje zahtjeva request.open ("GET", "processing.php", true); // 4. Pretplata na događaj onreadystatechange i njegova obrada pomoću anonimne funkcije request.addEventListener ("readystatechange", funkcija () (// ako su stanja zahtjeva 4 i status zahtjeva je 200 (OK) ako ((request.readyState = = 4) && (request.status == 200)) (// na primjer, prikazati XHR objekat u konzoli pretraživača console.log (zahtjev); // i odgovor (tekst) primljen od servera u konzoli upozorenja .log (request.responseText) ; // dobijemo element c id = welcome var welcome = document.getElementById ("dobrodošli"); // zamijenite sadržaj elementa odgovorom sa servera welcome.innerHTML = request.responseText ;))); // 5. Slanje zahtjeva serveru request.send ();

Kao rezultat, datoteka welcome.html će imati sljedeći kod:

Primjer rada AJAX-a

Primjer rada AJAX-a

Na serveru (pomoću php-a):

  1. Hajde da uzmemo podatke. Ako se podaci šalju putem GET metode, onda iz globalnog niza $_GET ["name"]. A ako se podaci prenose metodom POST, onda iz globalnog niza $ _POST ["name"].
  2. Koristeći ove podatke, izvršimo neke radnje na serveru. Kao rezultat toga, dobićemo neki odgovor. Hajde da to ponovimo.

Izrada asinhronog AJAX zahtjeva (POST metoda)

Modificirajmo gornji primjer. Sada će se AJAX zahtjev prema serveru izvršiti nakon klika na dugme. Primit će ime koje je korisnik unio u input element i poslati ga putem POST metode na server. Nakon što dobijete odgovor od servera, zamenite sadržaj elementa div na stranici sa njim.

Primjer rada AJAX-a

Primjer rada AJAX-a



Top srodni članci