Introduzione alla funzione fetch()

Matt Gaunt

fetch() consente di effettuare richieste di rete simili a XMLHttpRequest (XHR). La la differenza principale è che l'API Fetch utilizza Promises, che ha un'API più semplice per aiutarti a evitare le complicate chiamate nella API XMLHttpRequest.

Supporto dei browser

  • Chrome: 42.
  • Edge: 14.
  • Firefox: 39.
  • Safari: 10.1.

Origine

Se non hai mai utilizzato Promesse prima, dai un'occhiata ad Introduzione alle promesse di JavaScript.

Richiesta di recupero di base

Ecco un esempio implementato con un XMLHttpRequest e poi con fetch. Vogliamo richiedere un URL, ottenere una risposta e analizzare come JSON.

XMLHttpRequest

Un XMLHttpRequest ha bisogno di due listener per gestire il successo e casi di errore, nonché una chiamata a open() e send(). Esempio tratto dalla documentazione MDN.

function reqListener() {
    var data = JSON.parse(this.responseText);
    console.log(data);
}

function reqError(err) {
    console.log('Fetch Error :-S', err);
}

var oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.onerror = reqError;
oReq.open('get', './api/some.json', true);
oReq.send();

Recupero

La nostra richiesta di recupero è simile alla seguente:

fetch('./api/some.json')
  .then(
  function(response) {
    if (response.status !== 200) {
      console.log('Looks like there was a problem. Status Code: ' +
        response.status);
      return;
    }

    // Examine the text in the response
    response.json().then(function(data) {
      console.log(data);
    });
  }
  )
  .catch(function(err) {
    console.log('Fetch Error :-S', err);
  });

La richiesta fetch() richiede una sola chiamata per svolgere le stesse operazioni dell'XHR esempio. Per elaborare la risposta, verifichiamo innanzitutto che lo stato della risposta sia 200, quindi analizza la risposta come JSON. La risposta a una richiesta fetch() è un Stream, il che significa che dopo chiamiamo il metodo json(), viene restituita una promessa. Lo stream avviene in modo asincrono.

Metadati della risposta

L'esempio precedente mostrava lo stato del Response e come analizzare la risposta come JSON. Ecco come gestire altri metadati che potresti volere a cui accedere, come le intestazioni:

fetch('users.json').then(function(response) {
    console.log(response.headers.get('Content-Type'));
    console.log(response.headers.get('Date'));

    console.log(response.status);
    console.log(response.statusText);
    console.log(response.type);
    console.log(response.url);
});

Tipi di risposta

Quando effettuiamo una richiesta di recupero, la risposta riceve un response.type di "basic", "cors" o "opaque". Questi types mostrano da dove proviene la risorsa ed è possibile usarle per determinare come trattare l'oggetto di risposta.

Quando il browser richiede una risorsa sulla stessa origine, la risposta ha un Tipo di basic con limitazioni su ciò che puoi visualizzare dalla risposta.

Se viene effettuata una richiesta per una risorsa su un'altra origine e questa viene restituita Intestazioni COR, il tipo è cors. cors sono simili alle risposte basic, ma limitano le intestazioni che possono visualizzare per Cache-Control, Content-Language, Content-Type, Expires, Last-Modified e Pragma.

Le risposte opaque provengono da un'origine diversa che non restituisce CORS intestazioni. Se la risposta è opaca, non leggere i dati restituiti o visualizzare lo stato della richiesta, il che significa che non puoi per vedere se la richiesta è andata a buon fine.

Puoi definire una modalità per una richiesta di recupero in modo che solo determinati tipi di richieste risolvere il problema. Le modalità che puoi impostare sono le seguenti:

  • same-origin riesce solo per le richieste per risorse sulla stessa origine e rifiuta tutte le altre richieste.
  • cors consente le richieste di asset sulla stessa origine e su altre origini che restituiscono le intestazioni COR appropriate.
  • cors-with-forced-preflight esegue un preflight controlla prima di effettuare qualsiasi richiesta.
  • no-cors è destinato a effettuare richieste ad altre origini che non hanno CORS intestazioni e generare una risposta opaque, ma, come detto, non si tratta possibili nell'ambito globale della finestra al momento.

Per definire la modalità, aggiungi un oggetto opzioni come secondo parametro nella fetch e definire la modalità in quell'oggetto:

fetch('http://some-site.com/cors-enabled/some.json', {mode: 'cors'})
    .then(function(response) {
    return response.text();
    })
    .then(function(text) {
    console.log('Request successful', text);
    })
    .catch(function(error) {
    log('Request failed', error)
    });

Promesso di concatenamento

Una delle caratteristiche più importanti delle promesse è la capacità di collegarle tra loro. Per fetch(), questo ti consente di condividere la logica tra le richieste di recupero.

Se utilizzi un'API JSON, devi controllarne lo stato e analizzare JSON per ogni risposta. Puoi semplificare il codice definendo lo stato e L'analisi JSON in funzioni separate che restituiscono promesse e utilizzano il recupero per gestire solo i dati finali e il caso di errore.

function status(response) {
    if (response.status >= 200 && response.status < 300) {
    return Promise.resolve(response)
    } else {
    return Promise.reject(new Error(response.statusText))
    }
}

function json(response) {
    return response.json()
}

fetch('users.json')
    .then(status)
    .then(json)
    .then(function(data) {
    console.log('Request succeeded with JSON response', data);
    }).catch(function(error) {
    console.log('Request failed', error);
    });

Questo esempio definisce una funzione status che controlla response.status e restituisce una promessa risolta come Promise.resolve(), o una promessa rifiutata come Promise.reject(). Questo è il primo metodo chiamato nella catena fetch().

Se la promessa si risolve, lo script chiama il metodo json(), che restituisce una seconda promessa dalla chiamata response.json() e crea un contenente il codice JSON analizzato. Se l'analisi non riesce, la promessa viene viene rifiutata e viene eseguita l'istruzione catch.

Questa struttura ti consente di condividere la logica tra tutte le richieste di recupero, più facile da gestire, leggere e testare.

Richiesta POST

A volte un'app web deve chiamare un'API con un metodo POST e includere alcuni parametri nel corpo della richiesta. Per farlo, imposta method e body nelle opzioni fetch():

fetch(url, {
    method: 'post',
    headers: {
        "Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
    },
    body: 'foo=bar&lorem=ipsum'
    })
    .then(json)
    .then(function (data) {
    console.log('Request succeeded with JSON response', data);
    })
    .catch(function (error) {
    console.log('Request failed', error);
    });

Invia le credenziali con una richiesta di recupero

Per effettuare una richiesta di recupero con credenziali come i cookie, imposta il valore credentials valore in "include":

fetch(url, {
    credentials: 'include'
})