Interfața FETCH în Javascript

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, truedacă 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 ca FormDataobiect (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.bodyeste 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 exemplu POST,
  • body– organul de solicitare, unul dintre:
    • un șir (de exemplu, codificat JSON),
    • FormDataobiect, de a transmite datele ca form/multipart,
    • BlobBufferSourcepentru a trimite date binare,
    • URLSearchParams , pentru a trimite datele în x-www-form-urlencodedcodificare, folosit rar.

Formatul JSON este folosit de cele mai multe ori.

De exemplu, acest cod trimite userobiectul 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– trueeste 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 ca FormDataobiect (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) ca stringFormDataBufferSourceBlobsau UrlSearchParamsobiect.

Articol preluluat si tradus de AICI

logo 3data
logo 3data

Lasă un răspuns

Acest site folosește Akismet pentru a reduce spamul. Află cum sunt procesate datele comentariilor tale.