API-ul Fetch
Funcția fetch
API-ul Fetch oferă un instrument simplificat, dar în același timp flexibil și puternic, pentru accesarea resurselor de rețea comparativ cu XMLHttpRequest-ul standard.
Elementul cheie al acestui API Fetch este funcția fetch(). Ea este implementată în diferite contexte. În particular, în browser, este implementată de interfața Window.
Funcția fetch are următorea sintaxă:
const fetchPromise = fetch(resource [, init])
Ca parametru obligatoriu, resource, funcția acceptă parametrii resursei căreia funcția va accesa. Ca parametru opțional, init, funcția poate accepta un obiect cu setări suplimentare ale solicitării.
Funcția fetch() returnează un obiect Promise, care primește un răspuns după finalizarea solicitării către resursa de rețea.
Definirea resursei pe server
Să examinăm cel mai simplu exemplu. Așadar, mai întâi de toate, vom avea nevoie de o anumită resursă de rețea la care să accesăm. Pentru a emula o resursă de rețea, vom folosi un server web local.
Serverul web poate fi oricare. În acest caz, vom folosi varianta cea mai simplă - Node.js, deci înainte de a crea aplicația, este necesar să instalăm Node.js. Dar, din nou, în loc de Node.js, ar putea fi orice altă tehnologie de server - php, asp.net, python etc., sau un anumit server web cum ar fi Apache sau IIS.
Deci, să creăm pe discul dur un folder pentru fișierele serverului web. De exemplu, în cazul meu este folderul C:\app. Apoi, în acest folder, definim fișierul serverului. Să presupunem că se numește server.js și are următorul cod:
const http = require("http");
const fs = require("fs");
http.createServer(function(request, response){
if(request.url == "/hello"){
response.end("Fetch pe FDC.COM");
}
else{
fs.readFile("index.html", (error, data) => response.end(data));
}
}).listen(3000, ()=>console.log("Serverul a fost lansat la adresa http://localhost:3000"));
Acesta este cel mai primitiv server, care este suficient pentru sarcina noastră. Să trecem rapid prin cod. Mai întâi, sunt conectate pachetele cu funcționalitatea pe care intenționăm să o folosim:
const http = require("http"); // pentru procesarea solicitărilor de intrare
const fs = require("fs"); // pentru citirea fișierului index.html de pe discul dur
Pentru a crea serverul se folosește funcția http.createServer(). Acestei funcții i se transmite un handler, care este apelat de fiecare dată când serverul primește o solicitare. Handler-ul are doi parametri: request (conține datele solicitării) și response (gestionează trimiterea răspunsului).
În handler-ul solicitării, folosind proprietatea request.url, putem afla la ce resursă de pe server s-a făcut solicitarea. Astfel, în acest caz, dacă a venit o solicitare pe calea "/hello" (condițional la resursa "/hello"), atunci trimitem ca răspuns cu metoda response.end() textul "Fetch pe FDC.COM":
if(request.url == "/hello"){
response.end("Fetch pe FDC.COM");
}
Dacă solicitarea a venit la o altă resursă, atunci trimitem fișierul index.html, pe care îl vom defini mai departe:
else{
fs.readFile("index.html", (error, data) => response.end(data));
}
Pentru citirea fișierelor se folosește funcția încorporată fs.readFile(). Primul parametru al funcției este adresa fișierului (în acest caz se presupune că fișierul index.html se află în aceeași directorie cu fișierul serverului server.js). Al doilea parametru este o funcție care este apelată după citirea fișierului și primește conținutul acestuia prin al doilea parametru data. Apoi, conținutul citit poate fi trimis folosind funcția response.end(data).
La final, folosind funcția listen() lansăm serverul web pe portul 3000. Astfel, serverul va fi accesibil la adresa http://localhost:3000/
Apelul funcției fetch()
Acum, în directorul serverului, definim un fișier simplu index.html
Definim următorul conținut în acest fișier:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>FDC.COM</title>
</head>
<body>
<script>
fetch("/hello")
.then(response => response.text())
.then(responseText => console.log(responseText));
</script>
</body>
</html>
În funcția fetch() este transmisă adresa resursei - în acest caz "/hello".
fetch("/hello")
Deoarece fetch() returnează un obiect Promise, pentru a obține rezultatul solicitării, putem apela metoda then()
fetch("/hello").then(response => response.text())
În metoda then() este transmisă o funcție callback care, ca parametru response, primește răspunsul de la server. Cu toate acestea, răspunsul serverului reprezintă un obiect complex, care încapsulează multe informații diferite. Ne interesează doar textul trimis de server. Pentru a obține acest text, se apelează metoda response.text() a obiectului response.
Metoda response.text() returnează, de asemenea, un Promise. Și pentru a obține textul răspunsului propriu-zis, atașăm o altă metodă then(), în care în funcția callback obținem textul răspunsului:
.then(responseText => console.log(responseText));
Acum, în consolă, ne mutăm în directorul serverului folosind comanda cd și lansăm serverul folosind comanda:
node server.js
După lansarea serverului, putem accesa în browser adresa http://localhost:3000, unde ne va fi afișată pagina, iar în codul JavaScript al acesteia, cu ajutorul funcției fetch(), se va realiza o solicitare către resursa "/hello":
În final, la accesarea resursei "/hello", serverul va trimite șirul "Fetch pe FDC.COM", pe care îl vom putea obține pe pagina web.
În exemplul de mai sus s-a folosit un path relativ, dar se putea utiliza și un path absolut cu specificarea protocolului, adresei serverului și portului:
fetch("http://localhost:3000/hello")
.then(response => response.text())
.then(responseText => console.log(responseText));
fetch cu async/await
Deoarece funcția fetch() returnează un Promise, în loc să folosim lanțul de metode then(), putem folosi operatorii async/await pentru a extrage răspunsul. Să rescriem exemplul anterior:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>FDC.COM</title>
</head>
<body>
<script>
async function getText() {
// obținem obiectul răspuns
const response = await fetch("/hello");
// extragem textul răspunsului din obiectul răspuns
const responseText = await response.text();
console.log(responseText);
}
getText();
</script>
</body>
</html>