Primirea răspunsului - Obiectul Response și proprietățile sale
Pentru reprezentarea răspunsului de la server în API-ul Fetch se utilizează interfața Response. Funcția fetch() returnează un obiect Promise, funcția callback din care primește ca parametru un obiect Response cu răspunsul primit de la server:
fetch("/hello").then(response => /* acțiuni cu response */ )
Sau se poate folosi async/await pentru a obține obiectul Response:
async function getText() {
// obținem obiectul răspuns
const response = await fetch("http://localhost:3000/hello");
// acțiuni cu obiectul response .......
}
Cu ajutorul proprietăților obiectului Response se poate obține diverse informații din răspunsul primit. Obiectul Response are următoarele proprietăți:
- body: conținutul răspunsului sub formă de obiect ReadableStream
- bodyUsed: păstrează o valoare booleană care indică dacă conținutul răspunsului a fost deja folosit sau nu
- headers: setul de antete ale răspunsului sub formă de obiect Headers
- ok: păstrează o valoare booleană care indică dacă solicitarea a fost finalizată cu succes (adică dacă codul de stare al răspunsului se află în intervalul 200-299)
- redirected: păstrează o valoare booleană care indică dacă răspunsul este rezultatul unei redirecționări
- status: păstrează codul de stare al răspunsului
- statusText: păstrează mesajul de stare care corespunde codului de stare
- type: păstrează tipul răspunsului
- url: păstrează adresa URL. Dacă în procesul solicitării are loc o serie de redirecționări, atunci păstrează adresa URL finală după toate redirecționările
Este de menționat că toate aceste proprietăți sunt doar pentru citire. De exemplu, utilizăm o serie de proprietăți pentru a obține informații despre răspunsul serverului. Pentru aceasta, definim următorul server pe Node.js, care procesează solicitările:
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"));
Pe pagina index.html apelăm funcția fetch și obținem informații despre răspuns:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>FDC.COM</title>
</head>
<body>
<script>
fetch("/hello")
.then(response => {
console.log(response.status); // 200
console.log(response.statusText); // OK
console.log(response.url); // http://localhost:3000/hello
});
</script>
</body>
</html>
Exemplu similar cu async/await:
getResponse();
async function getResponse() {
const response = await fetch("/hello");
console.log(response.status); // 200
console.log(response.statusText); // OK
console.log(response.url); // http://localhost:3000/hello
}
Proprietatea ok returnează true dacă codul de stare al răspunsului se află în intervalul de la 200 la 299, ceea ce de obicei indică faptul că solicitarea a fost executată cu succes. Și putem verifica această proprietate înainte de a procesa răspunsul:
fetch("/hello").then(response => {
if(response.ok){
// procesarea răspunsului
}
});
Obținerea antetelor
Cu ajutorul proprietății headers se pot obține antetele răspunsului, care reprezintă interfața Headers.
Pentru a obține date din antete, putem folosi unul dintre următoarele metode ale interfeței Headers:
- entries(): returnează un iterator, care permite să trecem prin toate antetele
- forEach(): realizează parcurgerea antetelor
- get(): returnează valoarea unui anumit antet
- has(): returnează true, dacă este setat un anumit antet
- keys(): obține toate numele antetelor setate
- values(): obține toate valorile antetelor setate
De exemplu, obținem toate antetele răspunsului:
fetch("/hello").then(response => {
for(header of response.headers){
console.log(header[0],":",header[1]);
}
});
Fiecare antet reprezintă un array din două elemente, unde primul element este numele antetului, iar al doilea - valoarea sa.
Output-ul consolei browserului în cazul meu:
connection : keep-alive
content-length : 22
date : Fri, 03 Dec 2021 17:09:34 GMT
keep-alive : timeout=5
Alt exemplu - verificarea unui antet și la prezența sa afișarea valorii sale:
fetch("/hello").then(response => {
const headerTitle = "date"; // numele antetului
if(response.headers.has(headerTitle)){ // dacă antetul există
console.log(response.headers.get(headerTitle)); // obținem valoarea sa
}
});
Astfel, putem obține și antetele personalizate, care sunt setate de către server. De exemplu, să presupunem că serverul node.js setează antetul "Secret-Code":
const http = require("http");
const fs = require("fs");
http.createServer(function(request, response){
if(request.url == "/hello"){
response.setHeader("Secret-Code", 124);
response.end("Fetch pe METANIT.COM");
}
else{
fs.readFile("index.html", (error, data) => response.end(data));
}
}).listen(3000, ()=>console.log("Serverul a fost lansat la adresa http://localhost:3000"));
Pentru setarea antetului în node.js se folosește metoda response.setHeader(), primul parametru al căreia este numele antetului, iar al doilea - valoarea sa.
Obținem acest antet pe pagina web:
fetch("/hello").then(response => {
console.log(response.headers.get("Content-Type")); // null - antetul nu este setat
console.log(response.headers.get("Secret-Code")); // 124
});
Dacă antetul nu este setat, atunci metoda response.headers.get() returnează null.
Redirecționarea
Dacă în procesul solicitării a avut loc o redirecționare, atunci proprietatea redirected este egală cu true, iar proprietatea url păstrează adresa la care a avut loc redirecționarea. De exemplu, să presupunem că serverul pe node.js efectuează redirecționarea de la adresa "/hello" la adresa "/newpage":
const http = require("http");
const fs = require("fs");
http.createServer(function(request, response){
if(request.url == "/hello"){
response.statusCode = 302; // 302 - codul de redirecționare temporară
response.setHeader("Location", "/newpage"); // redirecționare la adresa localhost:3000/newpage
response.end();
}
else if(request.url == "/newpage"){
response.setHeader("Secret-Code", "New Page Code: 567"); // pentru test, setăm antetul
response.end("This is a new page");
}
else{
fs.readFile("index.html", (error, data) => response.end(data));
}
}).listen(3000, ()=>console.log("Serverul a fost lansat la adresa http://localhost:3000"));
Efectuăm o solicitare la adresa "/hello" pe pagina web:
fetch("/hello").then(response =>{
if (response.redirected) {
console.log("A avut loc redirecționarea la adresa", response.url);
console.log(response.headers.get("Secret-Code"));
}
});
Output-ul consolei browserului:
A avut loc redirecționarea la adresa
http://localhost:3000/newpage
New Page Code: 567
Din output-ul consolei, și anume din antetul Secret-Code, vedem că funcția fetch a primit răspuns de la noua adresă - "/newpage".