Pentru ca de curand am avut nevoie sa folosim acesata facilitate implementata in Javascript de la versiunea ECMAScript 5 incoace, iata o scurta sinteza a metodelor Fetch API, folosite de noi in dezvoltarea capabilitatilor PWA pentru un magazin virtual.
Comanda Fetch()
vă permite să faceți solicitări de rețea similare cu XMLHttpRequest (XHR) folosind un API mai simplu si mai curat folosind un obiect Promise. (despre interfata Promise intr-un alt tutorial). JavaScript poate trimite solicitări de rețea către un server și poate încărca informații noi ori de câte ori este nevoie. De exemplu, putem folosi o solicitare de rețea pentru a:
- Trimiteți o comandă,
- Încărcați informații despre utilizator,
- Primiți cele mai recente actualizări de la server,
- …etc.
… Și toate acestea fără a reîncărca pagina!
Există un termen umbrelă „AJAX” (abreviat A synchronous J avaScript și X ML ) pentru solicitările de rețea din JavaScript. Nu trebuie să folosim XML totuși: termenul vine din vremuri vechi, de aceea există cuvântul respectiv. Poate că ați auzit deja acest termen.
Există mai multe moduri de a trimite o solicitare de rețea și de a obține informații de la server.
Metoda fetch()
este modernă și versatilă, așa că vom începe cu ea. Nu este suportata de browserele vechi (poate fi folosit un polyfill), dar foarte bine suportata printre cele moderne.
Sintaxa de bază este:
let promise = fetch(url, [options])
Fără options
, aceasta este o simplă solicitare GET, care descarcă conținutul fișierului url
.
Browserul pornește imediat solicitarea și returnează o promisiune pe care ar trebui să o folosească codul de apel pentru a obține rezultatul.
Obținerea unui răspuns este de obicei un proces în două etape.
Mai întâi, obiectul promise
, returnat , se rezolvă cu un obiect din clasa de răspuns
fetch
încorporată de îndată ce serverul răspunde cu antetul corespunzator.
În această etapă putem verifica starea HTTP, pentru a vedea dacă are succes sau nu, verificăm anteturile, dar nu avem încă corpul (body) raspunsului.
Promisiunea respinge dacă fetch
nu a reușit să facă o solicitare HTTP, de exemplu probleme de rețea, sau nu există un astfel de site. Stările HTTP anormale, cum ar fi 404 sau 500, nu provoacă o eroare.
Putem vedea starea HTTP în proprietățile de răspuns:
status
– Cod de stare HTTP, de exemplu 200.ok
– boolean,true
dacă codul de stare HTTP este 200-299.
De exemplu:
let response = await fetch(url);
if (response.ok) { // if HTTP-status is 200-299
// get the response body (the method explained below)
let json = await response.json();
} else {
alert("HTTP-Error: " + response.status);
}
În al doilea rând, pentru a obține corpul răspunsului, trebuie să folosim un apel suplimentar de metodă.
Response
oferă mai multe metode bazate pe promisiuni pentru a accesa corpul în diferite formate:
response.text()
– citiți răspunsul și reveniți ca text,response.json()
– analizați răspunsul ca JSON,response.formData()
– returnează răspunsul caFormData
obiect (explicat în capitolul următor ),response.blob()
– returnează răspunsul ca Blob (date binare cu tip),response.arrayBuffer()
– returnează răspunsul ca ArrayBuffer (reprezentare la nivel scăzut a datelor binare),- în plus,
response.body
este un obiect ReadableStream , vă permite să citiți corpul bucată cu bucată, vom vedea un exemplu mai târziu.
De exemplu, să obținem un obiect JSON cu cele mai recente comite de la GitHub:
let url = 'https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits';
let response = await fetch(url);
let commits = await response.json(); // read response body and parse as JSON
alert(commits[0].author.login);
Sau, la fel fără await
, folosind sintaxa pure promises:
fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits')
.then(response => response.json())
.then(commits => alert(commits[0].author.login));
Pentru a obține textul de răspuns, await response.text()
în loc de .json()
:
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits');
let text = await response.text(); // read response body as text
alert(text.slice(0, 80) + '...');
Headere răspuns
Headerele răspunsului sunt disponibile într-un obiect antet asemănător obiectului dîn response.headers
:
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits');
// get one header
alert(response.headers.get('Content-Type')); // application/json; charset=utf-8
// iterate over all headers
for (let [key, value] of response.headers) {
alert(`${key} = ${value}`);
}
solicitări POST
Pentru a face o cerere POST
sau o cerere cu o altă metodă, trebuie să folosim optiunile fetch
:
method
– metoda HTTP, de exempluPOST
,body
– organul de solicitare, unul dintre:- un șir (de exemplu, codificat JSON),
FormData
obiect, de a transmite datele caform/multipart
,Blob
/BufferSource
pentru a trimite date binare,- URLSearchParams , pentru a trimite datele în
x-www-form-urlencoded
codificare, folosit rar.
Formatul JSON este folosit de cele mai multe ori.
De exemplu, acest cod trimite user
obiectul ca JSON:
let user = {
name: 'John',
surname: 'Smith'
};
let response = await fetch('/article/fetch/post/user', {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(user)
});
let result = await response.json();
alert(result.message);
Vă rugăm să rețineți, dacă cererea body
este un șir, atunci Content-Type
antetul este setat în text/plain;charset=UTF-8
, mod implicit.
Dar, pe măsură ce vom trimite JSON, folosim optiunea headers
de a trimite application/json
, în schimb, cea corectă Content-Type
pentru datele codificate în JSON.
Cum se trimite o imagine
De asemenea, putem trimite date binare fetch
folosind obiectele Blob
sau BufferSource
.
În acest exemplu, există un obiect <canvas>
în care putem genera o imagine Imaginea este trimisa catre către server:
<body style="margin:0">
<canvas id="canvasElem" width="100" height="80" style="border:1px solid"></canvas>
<input type="button" value="Submit" onclick="submit()">
<script>
canvasElem.onmousemove = function(e) {
let ctx = canvasElem.getContext('2d');
ctx.lineTo(e.clientX, e.clientY);
ctx.stroke();
};
async function submit() {
let blob = await new Promise(resolve => canvasElem.toBlob(resolve, 'image/png'));
let response = await fetch('/article/fetch/post/image', {
method: 'POST',
body: blob
});
// the server responds with confirmation and the image size
let result = await response.json();
alert(result.message);
}
</script>
</body>
Funcția submit()
poate fi rescrisă fără async/await
astfel:
function submit() {
canvasElem.toBlob(function(blob) {
fetch('/article/fetch/post/image', {
method: 'POST',
body: blob
})
.then(response => response.json())
.then(result => alert(JSON.stringify(result, null, 2)))
}, 'image/png');
}
Rezumat
O solicitare tipică de preluare constă din două apeluri await:
let response = await fetch(url, options); // resolves with response headers
let result = await response.json(); // read body as json
Sau, fara await
:
fetch(url, options)
.then(response => response.json())
.then(result => /* process result */)
Proprietăți de răspuns:
response.status
– codul HTTP al răspunsului,response.ok
–true
este starea 200-299.response.headers
– Obiect asemănător hărții cu anteturi HTTP.
Metode pentru a obține corpul de răspuns:
response.text()
– returnează răspunsul ca text,response.json()
– analizați răspunsul ca obiect JSON,response.formData()
– returnează răspunsul caFormData
obiect (codare formă/multipart, vezi capitolul următor),response.blob()
– returnează răspunsul ca Blob (date binare cu tip),response.arrayBuffer()
– returnează răspunsul ca ArrayBuffer (date binare de nivel scăzut),
Opțiuni de preluare până acum:
method
– metoda HTTP,headers
– un obiect cu anteturi de solicitare (nu este permis niciun antet),body
– datele de trimis (corpul cererii) castring
,FormData
,BufferSource
,Blob
sauUrlSearchParams
obiect.
Articol preluluat si tradus de AICI