Cum se configurează smartphone-uri și PC-uri. Portal informativ

Trimiterea solicitărilor POST prin JavaScript. Preluarea datelor XML

Visul pentru care a fost creat Web-ul este comun spațiu informaționalîn care comunicăm prin schimbul de informații. Versatilitatea sa este o parte integrantă a acesteia: un link hipertext poate duce oriunde, fie că este vorba de informații personale, locale sau globale, schiță sau text revizuit.

Tim Bernes-Lee, World Wide Web: O foarte scurtă istorie personală

Protocol

Dacă tastați eloquentjavascript.net/17_http.html în bara de adrese a browserului dvs., browserul recunoaște mai întâi adresa serverului asociată cu numele eloquentjavascript.net și încearcă să deschidă Conexiune TCP pe portul 80 - portul implicit pentru HTTP. Dacă serverul există și acceptă conexiunea, browserul trimite ceva de genul:

GET /17_http.html HTTP / 1.1
Gazdă: eloquentjavascript.net
User-Agent: numele browserului

Serverul răspunde prin aceeași conexiune:

HTTP / 1.1 200 OK
Lungimea conținutului: 65585
Tip de conținut: text / html


... restul documentului

Browserul preia partea care urmează răspunsului după linie goalăși îl afișează ca document HTML.

Informațiile trimise de client se numesc cerere. Începe cu linia:

GET /17_http.html HTTP / 1.1

Primul cuvânt este metoda de solicitare. GET înseamnă că trebuie să obținem o anumită resursă. Alte metode comune sunt DELETE pentru ștergere, PUT pentru înlocuire și POST pentru trimiterea informațiilor. Rețineți că serverul nu este obligat să îndeplinească fiecare solicitare pe care o primește. Dacă alegeți un site aleatoriu și spuneți-i DELETE pagina principala- cel mai probabil va refuza.

Partea de după numele metodei este calea către resursa către care a fost trimisă cererea. În cel mai simplu caz, o resursă este doar un fișier de pe server, dar protocolul nu se limitează la această capacitate. O resursă poate fi orice lucru care poate fi transmis ca fișier. Multe servere creează răspunsuri din mers. De exemplu, dacă deschideți twitter.com/marijnjh, serverul va căuta în baza de date utilizatorul marijnjh, iar dacă îl găsește, va crea o pagină de profil pentru acel utilizator.

După calea resursei, prima linie a cererii menționează HTTP / 1.1 pentru a indica versiunea protocolului HTTP pe care îl folosește.

Răspunsul serverului începe, de asemenea, cu versiunea protocolului urmată de starea răspunsului - mai întâi codul de la trei cifre, apoi o linie.

HTTP / 1.1 200 OK

Codurile de stare care încep cu 2 indică cererile reușite. Codurile care încep cu 4 înseamnă că ceva a mers prost. 404 este cea mai faimoasă stare HTTP, indicând că resursa solicitată nu a fost găsită. Codurile care încep cu 5 indică o eroare pe server, dar nu din cauza solicitării.

Prima linie a unei cereri sau răspuns poate fi urmată de orice număr de linii de antet. Acestea sunt nume: șiruri de valoare care reprezintă Informații suplimentare despre o cerere sau un răspuns. Aceste anteturi au fost incluse în exemplu:

Lungimea conținutului: 65585
Tip de conținut: text / html
Ultima modificare: miercuri, 09 apr 2014 10:48:09 GMT

Aceasta determină dimensiunea și tipul documentului primit ca răspuns. V în acest caz este un document HTML de 65'585 de octeți. De asemenea, indică când documentul a fost modificat ultima dată.

În cea mai mare parte, clientul sau serverul determină ce anteturi să includă într-o cerere sau răspuns, deși unele antete sunt necesare. De exemplu, Host, care indică un nume de gazdă, ar trebui să fie inclusă în cerere, deoarece un server poate servi mai multe nume de gazdă pe o singură adresă IP, iar fără acest antet serverul nu va ști cu ce gazdă încearcă să comunice clientul.

După anteturi, atât cererea, cât și răspunsul pot specifica un șir gol, urmat de un corp care conține datele de transferat. Cererile GET și DELETE nu trimit date suplimentare, dar PUT și POST trimit. Unele răspunsuri, cum ar fi mesajele de eroare, nu necesită un corp.

Browser și HTTP

După cum am văzut în exemplu, browserul face o solicitare atunci când introducem adresa URL bara de adresa... Când este primit document HTML conține referințe la alte fișiere, cum ar fi imagini sau Fișiere JavaScript, sunt solicitate și de la server.

Un site web mediu poate conține cu ușurință între 10 și 200 de resurse. Pentru a le putea solicita mai rapid, browserele fac mai multe cereri în același timp, în loc să aștepte ca cererile să se termine una câte una. Astfel de documente sunt întotdeauna solicitate prin solicitări GET.

Pe Pagini HTML pot exista formulare care permit utilizatorilor să introducă informații și să le trimită la server. Iată un exemplu de formular:

Nume:

Mesaj:

Codul descrie un formular cu două câmpuri: unul mic cere un nume și unul mare pentru un mesaj. Când faceți clic pe butonul „Trimite”, informațiile din aceste câmpuri vor fi codificate într-un șir de interogare. Când atributul de metodă al elementului este GET, sau când nu este specificat deloc, șirul de interogare este introdus în URL-ul din câmpul de acțiune, iar browserul face o solicitare GET cu acel URL.

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

Începutul șirului de interogare este indicat de un semn de întrebare. Aceasta este urmată de perechi de nume și valori corespunzătoare atributul numelui câmpuri de formular și conținutul acelor câmpuri. Ampersand (&) este folosit pentru a le separa.

Mesajul trimis în exemplu conține șirul „Da?”, deși semnul întrebării a fost înlocuit cu un cod ciudat. Unele caractere din șirul de interogare trebuie să fie eliminate. Semnul întrebării este inclus și este reprezentat de codul% 3F. Există o regulă nescrisă conform căreia fiecare format trebuie să aibă o modalitate de a scăpa de caractere. Această regulă se numește codificare URL folosește un procent urmat de două cifre hexazecimale pentru a reprezenta codul caracterului. 3F zecimală ar fi 63, care este codul semnului întrebării. JavaScript are funcții encodeURIComponent și decodeURIComponent pentru codificare și decodare.

Console.log (encodeURIComponent ("Bună ziua și la revedere")); // → Salut% 20% 26% 20la revedere console.log (decodeURIComponent ("Bună ziua% 20% 26% 20la revedere")); // → Salut și la revedere

Dacă schimbăm atributul metodei de pe formularul din exemplul anterior în POST, Solicitare HTTP depunerea formularului se va face cu Metoda POST care va trimite șirul de interogare în corpul solicitării în loc să îl atașeze la adresa URL.

POST /example/message.html HTTP / 1.1
Lungimea conținutului: 24
Tip de conținut: aplicație / x-www-form-urlencoded

Nume = Jean & mesaj = Da% 3F

Cu acordul metoda GET utilizat pentru interogări care nu au efecte secundare, cum ar fi căutările. Cererile care modifică ceva pe server creează cont nou sau postați un mesaj, trebuie trimis prin metoda POST. Programe client ca un browser, ei știu că nu este necesar să facă cereri POST tocmai așa și uneori fac cereri GET neobservate de utilizator - de exemplu, pentru a descărca în avans conținut de care utilizatorul ar putea avea nevoie în curând.

În următorul capitol, ne vom întoarce la formulare și vom vorbi despre cum le putem crea cu JavaScript.

XMLHttpRequest

Interfața prin care JavaScript din browser poate face solicitări HTTP se numește XMLHttpRequest (observați cum sar dimensiunea literelor). A fost dezvoltat de Microsoft pentru browser Internet Explorer la sfârşitul anilor 1990. Atunci format XML a fost foarte popular în lumea software-ului de afaceri - și în această lume Microsoft s-a simțit întotdeauna ca acasă. Era atât de popular încât acronimul XML a fost fixat în fața interfeței pentru lucrul cu HTTP, deși acesta din urmă nu este asociat deloc cu XML.

Cu toate acestea, numele nu este complet lipsit de sens. Interfața vă permite să analizați răspunsurile ca și cum ar fi documente XML. Amestecarea a două lucruri diferite (parsarea cererii și a răspunsurilor) într-unul singur este, desigur, un design dezgustător, dar ce puteți face.

Când interfața XMLHttpRequest a fost adăugată la Internet Explorer, a devenit posibil să se facă lucruri care anterior erau foarte dificil de făcut. De exemplu, site-urile au început să afișeze liste de sfaturi instrumente în timp ce utilizatorul introduce ceva într-un câmp de text. Scriptul trimite text către server prin HTTP în același timp în care utilizatorul tastează. Un server care are o bază de date pentru opțiuni posibile introducere, caută printre intrările pentru cele care se potrivesc și le returnează pentru afișare. Arăta foarte bine - oamenii obișnuiau să aștepte ca întreaga pagină să se reîncarce după fiecare interacțiune cu site-ul.

Un alt browser important de atunci, Mozilla (mai târziu Firefox) nu dorea să rămână în urmă. Pentru a permite lucruri similare, Mozilla a copiat interfața împreună cu numele. Următoarea generație de browsere a urmat exemplul, iar astăzi XMLHttpRequest este standardul de facto.

Trimiterea unei cereri

Pentru a trimite o cerere simplă, creăm un obiect de cerere cu un constructor XMLHttpRequest și apelăm metodele open și send.

Var req = new XMLHttpRequest (); req.open („GET”, „example / data.txt”, false); req.send (null); console.log (req.responseText); // → Acesta este conținutul data.txt

Metoda deschisă stabilește cererea. În cazul nostru, am decis să facem o cerere GET pentru fișierul exemplu / data.txt. Adresele URL care nu încep cu un nume de protocol (de exemplu, http :) se numesc relative, adică sunt interpretate relativ document curent... Când încep cu o bară oblică (/), înlocuiesc calea curentă - partea de după numele serverului. Altfel, parte calea curentă până la ultima bară oblică este plasată înaintea adresei URL relative.

După deschiderea cererii, o putem trimite folosind metoda de trimitere. Argumentul este corpul cererii. Pentru cererile GET, este folosit null. Dacă al treilea argument de deschis a fost fals, trimiterea va reveni numai după primirea răspunsului la cererea noastră. Pentru a obține corpul răspunsului, putem citi proprietatea responseText a obiectului de solicitare.

Puteți obține și alte informații de la obiectul răspuns. Codul de stare este disponibil în proprietatea status, iar textul de stare este disponibil în statusText. Antetele pot fi citite din getResponseHeader.

Var req = new 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")); // → text / simplu

Numele antetului nu fac distincție între majuscule și minuscule. De obicei sunt scrise cu majusculă la începutul fiecărui cuvânt, de exemplu „Content-Type”, dar „content-type” sau „content-TyPe” vor descrie același titlu.

Browserul va adăuga unele anteturi de la sine, cum ar fi „Gazdă” și altele, de care serverul are nevoie pentru a calcula dimensiunea corpului. Dar puteți adăuga propriile antete cu metoda setRequestHeader. Acest lucru este necesar pentru cazuri specialeși necesită asistența serverului pe care îl accesați - este liber să ignorați anteturile pe care nu le poate gestiona.

Cereri asincrone

În exemplu, cererea a fost finalizată când apelul de trimitere se încheie. Acest lucru este convenabil deoarece proprietăți precum responseText sunt disponibile imediat. Dar asta înseamnă că programul nostru va aștepta în timp ce browserul și serverul comunică între ele. La conexiune proasta, un server slab sau dosar mare asta poate dura perioadă lungă de timp... Acest lucru este, de asemenea, rău, deoarece niciun handler de evenimente nu va fi declanșat în timp ce programul este în modul de așteptare - documentul nu va mai răspunde la acțiunile utilizatorului.

Dacă trecem true ca al treilea argument de deschis, cererea va fi asincronă. Aceasta înseamnă că atunci când apelați la trimitere, cererea este pusă în coadă pentru trimitere. Programul continuă să ruleze, iar browserul se ocupă de trimiterea și primirea datelor în fundal.

Dar în timp ce cererea este procesată, nu vom primi un răspuns. Avem nevoie de un mecanism care să notifice că datele au sosit și sunt gata. Pentru a face acest lucru, va trebui să ascultăm evenimentul „încărcare”.

Var req = new XMLHttpRequest (); req.open ("GET", "exemplu / data.txt", adevărat); req.addEventListener ("încărcare", funcție () (console.log ("Efectuat:", req.status);)); req.send (null);

La fel ca apelul la requestAnimationFrame din Capitolul 15, acest cod ne obligă să folosim stilul de programare asincronă prin împachetarea codului care ar trebui executat după solicitare într-o funcție și aranjarea apelului la această funcție în timpul potrivit... Vom reveni la asta mai târziu.

Preluarea datelor XML

Când resursa returnată de obiectul XMLHttpRequest este un document XML, proprietatea responseXML va conține vizualizarea analizată a documentului. Funcționează într-un mod similar cu DOM, cu excepția faptului că îi lipsește funcționalitatea inerentă a HTML, cum ar fi proprietatea stil. Obiectul conținut în responseXML corespunde obiectului document. Proprietatea sa documentElement se referă la eticheta externă a unui document XML. V următorul document(exemplu / fruit.xml) această etichetă ar fi:

Putem obține un fișier ca acesta:

Var req = new XMLHttpRequest (); req.open ("GET", "exemplu / fruct.xml", false); req.send (null); console.log (req.responseXML.querySelectorAll ("fruct"). length); // → 3

Documentele XML pot fi folosite pentru a face schimb cu serverul informatii structurate... Forma lor - etichete imbricate - este potrivită pentru stocarea majorității datelor, bine sau după macar mai bun decât fișiere text... Interfața DOM este incomodă în ceea ce privește preluarea informațiilor și documente XML sunt destul de verbose. De obicei, cel mai bine este să comunicați folosind date JSON, care sunt mai ușor de citit și scris, atât pentru programe, cât și pentru oameni.

Var req = new XMLHttpRequest (); req.open ("GET", "exemplu / fruit.json", false); req.send (null); console.log (JSON.parse (req.responseText)); // → (banana: „galben”, lămâie: „galben”, cireș: „roșu”)

Sandbox pentru HTTP

Solicitările HTTP de la o pagină web ridică probleme de securitate. Persoana care controlează scriptul poate avea interese diferite de cele ale utilizatorului pe computerul căruia rulează. Mai exact, dacă merg pe themafia.org, nu vreau ca scripturile lor să poată interoga mybank.com folosind informațiile browserului meu ca identificator și să-mi spună să-mi trimit toți banii într-un cont de mafie.

Site-urile web se pot apăra împotriva unor astfel de atacuri, dar este nevoie de ceva efort și multe site-uri nu reușesc să le facă față. Din această cauză, browserele îi protejează împiedicând scripturile să facă solicitări către alte domenii (nume precum themafia.org și mybank.com).

Acest lucru poate interfera cu dezvoltarea sistemelor la care au nevoie de acces domenii diferite pentru un motiv bun. Din fericire, serverul poate include următorul antet în răspuns, spunând browserelor că cererea ar putea veni din alte domenii:

Acces-Control-Permite-Origine: *

Retragerea cererilor

Capitolul 10 în implementarea noastră sistem modular AMD am folosit funcția ipotetică backgroundReadFile. A luat un nume de fișier și o funcție și a apelat acea funcție după ce a citit conținutul fișierului. Aici implementare simplă aceasta functie:

Funcția backgroundReadFile (url, callback) (var req = nou XMLHttpRequest (); req.open ("GET", url, true); req.addEventListener ("încărcare", funcție () (dacă (req.status)< 400) callback(req.responseText); }); req.send(null); }

O abstractizare simplă facilitează utilizarea XMLHttpRequest pentru cereri GET simple. Dacă scrieți un program care face solicitări HTTP, este o idee bună să utilizați o funcție de ajutor, astfel încât să nu trebuiască să repetați modelul urât XMLHttpRequest tot timpul.

Argumentul callback este un termen folosit adesea pentru a descrie astfel de funcții. Funcția de apel invers este transmisă unui alt cod, astfel încât să ne poată suna mai târziu.

Nu este greu să scrii propria ta funcție de ajutor HTTP, adaptată special pentru programul tău. Cel precedent face doar cereri GET și nu ne oferă control asupra antetelor sau corpului cererii. Puteți scrie o altă variantă pentru cererea POST, sau una mai generală care acceptă diferite solicitări. Multe biblioteci JavaScript oferă wrapper-uri pentru XMLHttpRequest.

Principala problemă cu învelișul de mai sus este gestionarea erorilor. Când o solicitare returnează un cod de stare de eroare (400 sau mai mare), nu face nimic. Acest lucru este bine în unele cazuri, dar imaginați-vă că punem un indicator de încărcare pe pagină pentru a indica faptul că primim informații. Dacă cererea eșuează deoarece serverul s-a prăbușit sau conexiunea este întreruptă, pagina se va pretinde că este ocupată cu ceva. Utilizatorul va aștepta puțin, apoi se va plictisi și va decide că site-ul este un fel de prost.

Avem nevoie de o opțiune prin care primim o alertă de solicitare eșuată, astfel încât să putem lua măsuri. De exemplu, putem elimina mesajul de descărcare și putem informa utilizatorul că ceva a mers prost.

Gestionarea erorilor în codul asincron este chiar mai dificilă decât în ​​codul sincron. Deoarece adesea trebuie să separăm o parte din lucrări și să o plasăm într-o funcție de apel invers, domeniul de aplicare al blocului try este lipsit de sens. În următorul cod, excepția nu va fi capturată, deoarece apelul la backgroundReadFile revine imediat. Apoi controlul părăsește blocul try și funcția din acesta nu va fi apelată.

Încercați (backgroundReadFile ("exemplu / data.txt", funcția (text) (dacă (text! = "Așteptată")) aruncați o nouă eroare ("A fost neașteptată");));) catch (e) (console.log ( "Bună ziua de la blocul de captură");)

Pentru a procesa cererile nereușite, va trebui să trimiteți functie suplimentaraîn ambalajul nostru și apelați-l în caz de probleme. O altă opțiune este să folosiți convenția conform căreia, dacă cererea eșuează, un argument suplimentar este transmis funcției de apel invers care descrie problema. Exemplu:

Funcția getURL (url, callback) (var req = new XMLHttpRequest (); req.open ("GET", url, true); req.addEventListener ("încărcare", funcție () (dacă (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); }

Codul care utilizează getURL ar trebui să verifice dacă a fost returnată o eroare și să o gestioneze dacă există.

GetURL ("date / nonsense.txt", funcția (conținut, eroare) (dacă (eroare! = Null) console.log ("Eșuat la preluarea nonsense.txt:" + eroare); else console.log ("nonsense.txt : „+ conținut);));

Nu ajută cu excepții. Când efectuăm mai multe acțiuni asincrone consecutive, o excepție în orice punct al lanțului, în orice caz (cu excepția cazului în care înfășurați fiecare handler în propriul bloc try/catch) va cădea la nivelul superior și va rupe întregul lanț.

Promisiuni

Este greu să scrii cod asincron pentru proiecte complexe sub formă de simplu apeluri inverse... Este foarte ușor să uitați să verificați dacă există o eroare sau să permiteți unei excepții neașteptate să vă anuleze brusc programul. În plus, organizația prelucrare corectă erori și trecerea erorii prin mai multe apeluri succesive este foarte obositoare.

Au existat multe încercări de a rezolva această problemă cu abstracții suplimentare. Una dintre cele mai reușite încercări se numește promisiuni. Promisiunile înglobează o acțiune asincronă într-un obiect care poate fi trecut și care trebuie să facă ceva atunci când acțiunea se finalizează sau eșuează. O astfel de interfață a devenit deja parte a curentului versiuni JavaScript iar pentru versiunile mai vechi poate fi folosit ca bibliotecă.

Interfața promisiunilor nu este deosebit de intuitivă, dar puternică. În acest capitol, îl vom descrie doar parțial. Mai multe informatii poate fi găsit pe www.promisejs.org

Pentru a crea obiectul promises, numim constructorul Promise, oferindu-i o funcție de inițializare a acțiunii asincrone. Constructorul apelează această funcție și îi transmite două argumente, care sunt și ele funcții. Primul ar trebui chemat într-un caz de succes, celălalt într-un caz nereușit.

Și iată pachetul nostru pentru solicitările GET, care de data aceasta returnează o promisiune. Acum îl vom numi doar obține.

Funcția get (url) (return new Promise (funcție (reușită, eșec) (var req = new XMLHttpRequest (); req.open ("GET", url, true); req.addEventListener ("încărcare", funcția () () ( dacă (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); }); }

Rețineți că interfața cu funcția în sine a fost simplificată. Îi transmitem adresa URL, iar ea ne întoarce promisiunea. Acesta acționează ca un handler pentru ieșirea cererii. Are o metodă apoi care este apelată cu două funcții, una pentru a gestiona succesul și cealaltă pentru a gestiona eșecul.

Get ("exemplu / data.txt"). Apoi (funcție (text) (console.log ("data.txt:" + text);), funcție (eroare) (console.log ("Eșuat preluarea datelor.txt) : "+ eroare);));

Deși aceasta este încă una dintre modalitățile de a exprima ceea ce am făcut deja. Doar atunci când ai un lanț de evenimente vezi o diferență notabilă.

Apelarea produce apoi o nouă promisiune al cărei rezultat (valoarea transmisă gestionarilor de succes) depinde de valoarea returnată a primei funcție la care am transmis-o atunci. Această funcție poate returna o altă promisiune, indicând faptul că se realizează o muncă asincronă suplimentară. În acest caz, promisiunea returnată până atunci însăși va aștepta promisiunea returnată de funcția de gestionare, iar succesul sau eșecul va avea loc cu aceeași valoare. Când funcția de gestionare returnează o valoare care nu este promisă, promisiunea returnată până atunci reușește folosind acea valoare ca rezultat.

Aceasta înseamnă că puteți folosi apoi pentru a schimba rezultatul unei promisiuni. De exemplu, următoarea funcție returnează o promisiune al cărei rezultat este conținutul de la adresa URL dată analizată ca JSON:

Funcția getJSON (url) (return get (url) .then (JSON.parse);)

Ultimul apel apoi nu a desemnat un handler de eșec. Acest lucru este permis. Eroarea va fi transmisă promisiunii returnate atunci și de asta avem nevoie - getJSON nu știe ce să facă când ceva nu merge bine, dar există speranța că codul de apelare îl știe.

Ca exemplu care arată utilizarea promisiunilor, vom scrie un program care primește un număr de fișiere JSON de la server și afișează cuvântul „descărcare” în timpul executării cererii. Fișierele conțin informații despre persoane și link-uri către alte fișiere cu informații despre alte persoane în proprietăți precum tatăl, mama, soțul.

Trebuie să obținem numele mamei soțului/soției din exemplul / bert.json. În caz de probleme, trebuie să eliminăm textul „încărcare” și să afișăm un mesaj de eroare. Iată cum poți face asta cu promisiuni:

Programul rezultat este relativ compact și ușor de citit. Metoda catch este similară cu atunci, dar se așteaptă doar la un handler de rezultate nereușit și, dacă are succes, transmite rezultatul neschimbat. Execuția programului va continua în mod obișnuit după prinderea excepției - la fel ca și în cazul try/catch. Astfel, finalul apoi, care elimină mesajul de încărcare, se execută oricum, chiar dacă eșuează.

S-ar putea să vă gândiți la interfața de promisiune ca la un limbaj separat pentru gestionarea execuției programului în mod asincron. Apelurile suplimentare la metode și funcții care sunt necesare pentru a-l face să funcționeze fac ca codul să pară puțin ciudat, dar nu la fel de incomod ca gestionarea manuală a tuturor erorilor.

Apreciază HTTP

Când se creează un sistem cu care comunică un program JavaScript dintr-un browser (partea clientului). program server, puteți utiliza mai multe opțiuni pentru modelarea unei astfel de comunicări.

O tehnică comună este apelurile de procedură de la distanță. În acest model, comunicarea urmează modelul apelurilor de funcții obișnuite, doar aceste funcții sunt efectuate pe un alt computer. Apelul este de a crea o cerere către server, care include numele funcției și argumentele. Răspunsul la cerere include o valoare returnată.

Când utilizați apeluri de procedură la distanță, HTTP servește doar ca transport pentru comunicare și, cel mai probabil, veți scrie un strat de abstractizare care îl ascunde complet.

O altă abordare este să vă construiți sistemul de comunicare în jurul conceptului de resurse și metode HTTP. În loc de un apel de procedură la distanță numit addUser, o faci cerere PUT către / utilizatori / larry. În loc să codificați proprietăți personalizate în argumentele funcției, definiți formatul sau utilizarea documentului format existent care va reprezenta utilizatorul. Corpul PUT care face cerere noua resursa, va fi pur și simplu un document de acest format. O resursă este obținută printr-o solicitare GET către adresa sa URL (/ user / larry), care returnează un document reprezentând resursa.

A doua abordare facilitează utilizarea unora Capabilitati HTTP, de exemplu, suport pentru stocarea în cache a resurselor (o copie a resursei este stocată pe partea client). De asemenea, ajută la crearea unei interfețe consistente, deoarece este mai ușor de gândit în termeni de resurse decât în ​​termeni de funcții.

Securitate și HTTPS

Datele circulă pe internet pe o cale lungă și periculoasă. Pentru a ajunge la destinație, trebuie să sară peste tot felul de locuri, de la Rețele Wi-Fi cafenele la lanțuri controlate de diferite organizații si state. În orice moment pe drum, acestea pot fi citite sau chiar modificate.

Dacă trebuie să păstrați ceva secret, cum ar fi parolele de e-mail, sau datele trebuie să ajungă la destinație neschimbate, cum ar fi numărul contului bancar către care transferați bani, HTTP simplu nu este suficient.

Protocolul HTTP securizat, ale cărui adrese URL încep cu https: //, înglobează traficul HTTP într-un mod care este mai greu de citit și modificat. Clientul confirmă mai întâi că serverul este cine pretinde a fi, solicitând serverului să prezinte un certificat criptografic emis de o parte autorizată pe care browserul o recunoaște. Apoi, toate datele care trec prin conexiune sunt criptate pentru a preveni interceptarea și modificarea.

În acest fel, când totul funcționează corect, HTTPS previne atât cazurile în care cineva se pretinde a fi un alt site web cu care comunici, cât și cazurile de interceptare a comunicării tale. Nu este perfect și au existat deja cazuri în care HTTPS a eșuat din cauza certificatelor false sau furate sau a programelor defecte. Cu toate acestea, este foarte ușor să faci ceva rău cu HTTP, iar cracarea HTTPS necesită genul de efort care poate fi depus doar de agențiile guvernamentale sau organizațiile criminale foarte serioase (și uneori nu există diferențe între aceste organizații).

Rezultat

În acest capitol, am văzut că HTTP este un protocol pentru accesarea resurselor de pe Internet. Clientul trimite o cerere care conține o metodă (de obicei GET) și o cale care identifică resursa. Serverul decide ce să facă cu cererea și răspunde cu un cod de stare și un corp de răspuns. Solicitările și răspunsurile pot conține anteturi care transmit informații suplimentare.

Browserele fac solicitări GET pentru a obține resursele necesare redării paginii. O pagină poate conține formulare care permit transmiterea informațiilor introduse de utilizator într-o solicitare care este generată după trimiterea formularului. Veți afla mai multe despre acest lucru în capitolul următor.

Interfața prin care JavaScript face solicitări HTTP din browser se numește XMLHttpRequest. Puteți ignora prefixul „XML” (dar tot trebuie să îl scrieți). Poate fi folosit în două moduri: sincron, care blochează toate lucrările până la sfârșitul cererii, și asincron, care necesită instalarea unui handler de evenimente pentru a urmări sfârșitul cererii. În aproape toate cazurile, este de preferat mod asincron... Crearea cererii arată astfel:

Var req = new XMLHttpRequest (); req.open ("GET", "exemplu / data.txt", adevărat); req.addEventListener ("încărcare", funcție () (console.log (req.statusCode);)); req.send (null);

Programarea asincronă este dificilă. Promises sunt o interfață care simplifică, ajutând la rutarea mesajelor de eroare și a excepțiilor către gestionarea corectă și prin abstracția unor elemente repetitive, predispuse la erori.

Exerciții

Negociere de conținut
Unul dintre lucrurile pe care HTTP le poate face și despre care nu am discutat se numește negociere de conținut. Antetul Accept dintr-o cerere poate fi folosit pentru a spune serverului ce tipuri de documente dorește să primească clientul. Multe servere îl ignoră, dar atunci când serverul știe despre diferite moduri de a codifica resursa, se poate uita la antet și îl poate trimite pe cel pe care îl preferă clientul.

URL-ul eloquentjavascript.net/author este configurat să răspundă atât în ​​text simplu, cât și în HTML sau JSON, în funcție de solicitarea clientului. Aceste formate sunt definite de tipurile de conținut standardizate text / simplu, text / html și aplicație / json.

Trimiteți o solicitare pentru a primi toate cele trei formate pentru această resursă. Utilizați metoda setRequestHeader a obiectului XMLHttpRequest pentru a seta antetul Accept la unul dintre tipurile necesare conţinut. Asigurați-vă că setați antetul după deschidere, dar înainte de trimitere.

În cele din urmă, încercați să solicitați conținut precum aplicație/curcubee + unicorni și vedeți ce se întâmplă.

În așteptarea mai multor promisiuni
Constructorul Promise are o metodă all care, atunci când primește o serie de promisiuni, returnează o promisiune care așteaptă ca toate promisiunile specificate în matrice să se finalizeze. Apoi emite un rezultat de succes și returnează o matrice cu rezultatele. Dacă oricare dintre promisiunile din matrice eșuează, și promisiunea partajată eșuează (cu valoarea promisiunii eșuate din matrice).

Încercați așa ceva scriind funcția all.

Rețineți că, odată ce o promisiune este completă (când fie reușește, fie eșuează), aceasta nu poate reintroduce o eroare sau succes, iar apelurile de funcții ulterioare sunt ignorate. Acest lucru poate facilita gestionarea erorilor din promisiunea dvs.

Funcționează toate (promise) (return new Promise (funcție (reușită, eșec) (// Codul tău.));) // Cod de verificare. all (). apoi (funcție (matrice) (console.log ("Acesta ar trebui să fie:", matrice);)); function soon (val) (return new Promise (funcție (succes) (setTimeout (funcție () (succes (val);), Math.random () * 500);));) all (). apoi (funcție (matrice); ) (console.log ("Acesta ar trebui să fie:", matrice);)); function fail () (return new Promise (funcție (succes, fail) (fail (new Error ("bang"));));) all (). apoi (function (array) (console.log ("Ajungem aici) nu ar trebui ");), function (eroare) (daca (error.message! =" bang ") console.log ("Neaşteptat bummer: ", eroare);));

De mult timp, multe site-uri au pagini dinamice, adică se actualizează fără repornire. Acest lucru se realizează prin apeluri de server prin JavaScript, în cele mai multe cazuri, este solicitări POST și GET... Și aproape întotdeauna astfel de site-uri sunt folosite pentru asta Ajax... Și nu toată lumea știe (din păcate) asta Ajax nu este o limbă separată, ci doar o bibliotecă JavaScript... Concluzie: Ajax este doar mod convenabil trimite cereri POST, dar toate acestea se pot face fără ajutorul lui. Aici cum să trimiteți solicitări POST prin JavaScript fără Ajax, voi explica în acest articol.

Vom rezolva acum o problemă clasică - aceasta este însumarea a două numere specificate de utilizator. Adică numărăm din câmpurile de text 2 numere, trimiteți-le la server, obțineți răspunsul și afișați-le pe pagină. Și toate acestea fără reîncărcare a paginii.

Să începem simplu: scris Cod PHP:

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

Totul este elementar aici, așa că nici nu voi comenta. Și acum partea mai dificilă este partea clientului:










Suma este egală cu:


Cod HTML Nu voi comenta deoarece este complet transparent. Dar sa JavaScript Voi adăuga puțin, în ciuda comentariilor detaliate. În primul rând, funcția getXmlHttp () este versatil. Îl puteți copia în siguranță în scripturile dvs. Sarcina ei este să returneze astfel XMLHTTP pentru a-l face să funcționeze în orice browser. Pentru că cea mai populară opțiune este XMLHttpRequest nou () cu toate acestea nu funcționează, de exemplu în IE6... De asemenea, alte opțiuni nu sunt universale, așa că aici selectăm doar o opțiune de lucru pentru orice browser.

Am mai scris în comentarii despre „ lucru asincron ". Există și o opțiune sincronă. Singura diferență este că sincron până la primirea unui răspuns de la server, browserul nu va funcționa, doar atârnă. Îmi este greu să vin cu o astfel de sarcină acolo unde este nevoie, așa că am scris imediat opțiunea asincronă... Funcționează astfel: noi trimitem o cerere și așteptăm un răspuns, dar browserul nu se blochează... Și când vine răspunsul ( xmlhttp.readyState == 4), apoi procesăm imediat răspunsul. Aceasta este versiunea asincronă a lucrării, este puțin mai complicată, dar numai ea ar trebui folosită (cu excepția cazurilor foarte rare).

În acest fel Solicitările POST sunt trimise prin JavaScript... După cum puteți vedea Ajax nu aveam deloc nevoie. Și vă recomand cu tărie ca, dacă aveți doar câteva solicitări pentru întregul site, atunci nici măcar să nu vă gândiți să folosiți această bibliotecă grea, ci să folosiți materialul acestui articol.

O lecție în care vom folosi exemple pentru a crea cereri AJAX asincrone simple către server. Vom folosi atât metoda GET, cât și metoda POST ca metodă de transfer de cereri. Pe server, vom procesa cereri folosind scripturi PHP.

Ce este o solicitare AJAX asincronă?

Tehnologia AJAX este folosită în principal pentru a face cereri asincrone către server. O solicitare asincronă este o astfel de solicitare care este executată în fundalși nu împiedică utilizatorul să interacționeze cu pagina.

La trimiterea unei cereri asincrone, browserul (pagina) nu este „înghețat”, adică. cu ea, ca și înainte, poți lucra. Dar atunci de unde știi când va veni un răspuns de la server. Pentru a determina acest lucru, trebuie să monitorizați proprietatea readyState a browserului. Această proprietate conține un număr, după valoarea căruia poți judeca în ce stadiu se află cererea. Următorul tabel rezumă valorile de bază ale proprietății readyState și stările lor corespunzătoare.

Acestea. se dovedește că trebuie să urmărim când valoarea proprietății readyState este 4. Aceasta va însemna că un răspuns de la server a venit la cererea trimisă. Restul valorilor sunt rareori folosite în practică și este posibil ca unele browsere să nu le accepte.

Pentru a determina în ce etapă se află o solicitare, trebuie să utilizați evenimentul onreadystatechange al obiectului XMLHttpRequest. Acest eveniment apare ori de câte ori valoarea proprietății readyState se modifică. Prin urmare, în handlerul acestui eveniment (al unei funcții fără nume sau cu nume), puteți scrie acțiuni care vor verifica dacă această proprietate este egală cu 4 și, dacă este, de exemplu, să afișați răspunsul serverului pe pagină.

Efectuarea unei cereri AJAX asincrone (metoda GET)

Luați în considerare crearea unui asincron Solicitare AJAX de exemplu care, după încărcarea paginii, va saluta utilizatorul și va afișa adresa IP a acestuia.

Pentru a face acest lucru, trebuie să creați 2 fișiere pe server într-un singur director:

  1. welcome.html - pagină HTML care va fi afișată utilizatorului. În aceeași pagină vom plasa un script care va realiza totul acțiunile necesare pentru lucrul AJAX pe partea clientului.
  2. processing.php - fișier PHP care va procesa cererea din partea serverului și va forma răspunsul. Să începem dezvoltarea prin crearea structurii de bază a fișierului welcome.html.
Un exemplu de funcționare AJAX

Un exemplu de funcționare AJAX

Să ne uităm la secvența de acțiuni care trebuie efectuate pe partea clientului (în codul JavaScript):

    Să pregătim datele necesare pentru a executa cererea pe server. Dacă nu sunt necesare date pentru a executa interogarea pe server, atunci această etapă poate fi omisă.

    Să creăm o variabilă care va conține o instanță a obiectului XHR (XMLHttpRequest).

    Să configuram cererea folosind metoda deschisă ().

    Sunt specificați următorii parametri:

    • Metoda prin care cererea va fi trimisă către server (GET, POST).
    • Adresa URL care va gestiona cererea pe server.
    • Tip cerere: sincron (fals) sau asincron (adevărat).
    • Nume de utilizator și parolă, dacă este necesar.
  1. Abonați-vă la evenimentul onreadystatechange al obiectului XHR și specificați handlerul ca funcție anonimă sau numită. După aceea, vom crea un cod în interiorul acestei funcții care va verifica starea răspunsului și va efectua anumite acțiuni pe pagină. Răspunsul care vine de la server este întotdeauna în proprietatea responseText.

    Pe lângă verificarea valorii proprietății readyState cu numărul 4, puteți verifica valoarea proprietății status. Această proprietate determină starea cererii. Dacă este 200, atunci totul este în regulă. În caz contrar, a apărut o eroare (de exemplu, 404 - URL nu a fost găsit).

    Să trimitem o cerere către server folosind metoda send ().

    Dacă folosim metoda GET pentru a trimite o solicitare, atunci trecem datele în parametru aceasta metoda nu este nevoie. Acestea sunt transmise ca parte a adresei URL.

    Dacă folosim metoda POST pentru a trimite o solicitare, atunci datele trebuie să fie transmise ca parametru la metoda send (). În plus, înainte de a apela această metodă, trebuie să setați antetul Content-Type, astfel încât serverul să știe în ce codificare a venit cererea și să o poată decripta.

Conținutul elementului de script:

// 2. Creați o cerere variabilă var request = new XMLHttpRequest (); // 3. Configurarea cererii request.open ("GET", "processing.php", true); // 4. Abonarea la evenimentul onreadystatechange și procesarea acestuia folosind funcția anonimă request.addEventListener ("readystatechange", funcția () (// dacă stările cererii sunt 4 și starea solicitării este 200 (OK) if ((request.readyState = = 4) && (request.status == 200)) (// de exemplu, afișați obiectul XHR în consola browser console.log (request); // și răspunsul (text) primit de la server în consola de alertă .log (request.responseText) ; // obțineți elementul c id = welcome var welcome = document.getElementById ("binevenit"); // înlocuiți conținutul elementului cu răspunsul de la server welcome.innerHTML = request.responseText ;))); // 5. Trimiterea unei cereri către server request.send ();

Ca rezultat, fișierul welcome.html va avea următorul cod:

Un exemplu de funcționare AJAX

Un exemplu de funcționare AJAX

Pe server (folosind php):

  1. Să luăm datele. Dacă datele sunt trimise prin metoda GET, atunci din matricea globală $ _GET [„nume”]. Și dacă datele sunt transferate folosind metoda POST, atunci din matricea globală $ _POST [„nume”].
  2. Folosind aceste date, să efectuăm câteva acțiuni pe server. Ca urmare, vom primi un răspuns. Să-i facem ecou.

Efectuarea unei cereri AJAX asincrone (metoda POST)

Să modificăm exemplul de mai sus. Acum cererea AJAX către server va fi executată după ce faceți clic pe butonul. Acesta va primi numele pe care utilizatorul l-a introdus în elementul de intrare și îl va trimite prin metoda POST către server. După ce primiți un răspuns de la server, înlocuiți conținutul elementului div de pe pagină cu acesta.

Un exemplu de funcționare AJAX

Un exemplu de funcționare AJAX



Top articole similare