Wprowadzenie do pobierania()

fetch() umożliwia wysyłanie żądań sieciowych podobnych do XMLHttpRequest (XHR). Główna różnica polega na tym, że interfejs Fetch API korzysta z obiektu Promises, który ma prostszy interfejs API, dzięki czemu można uniknąć skomplikowanych wywołań zwrotnych w interfejsie XMLHttpRequest API.

Obsługa przeglądarek

  • Chrome: 42.
  • Krawędź: 14.
  • Firefox: 39.
  • Safari: 10.1

Źródło

Jeśli nigdy wcześniej nie korzystałeś(-aś) z obietnic, przeczytaj artykuł Wprowadzenie do obietnic w JavaScriptzie.

Podstawowe żądanie pobierania

Oto przykład zaimplementowanego parametru XMLHttpRequest a potem w aplikacji fetch. Chcemy wysłać żądanie do adresu URL, uzyskać odpowiedź i przeanalizować ją jako dane JSON.

XMLHttpRequest

XMLHttpRequest potrzebuje 2 detektorów, aby obsłużyć sukces i błędów oraz połączenie z numerami open() i send(). Przykład z dokumentacji MDN.

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

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

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

Pobierz

Nasze żądanie pobierania wygląda tak:

fetch('./api/some.json')
  .then(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(err => {
    console.log('Fetch Error :-S', err);
  });

Żądanie fetch() wymaga tylko 1 wywołania, aby wykonać tę samą pracę co przykład XHR. Aby przetworzyć odpowiedź, najpierw sprawdzamy, czy stan odpowiedzi to 200, a potem parsujemy ją jako JSON. Odpowiedź na żądanie fetch() to obiekt Stream, co oznacza, że po wywołaniu metody json() zwracana jest obietnica. Transmisja odbywa się asynchronicznie.

Metadane odpowiedzi

W poprzednim przykładzie pokazaliśmy stan Response (Odpowiedź). i prześle ją do formatu JSON. Oto jak postępować z innymi metadanymi, które mogą Ci się przydać takie jak nagłówki:

fetch('users.json').then(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);
});

Typy odpowiedzi

Gdy wykonujemy żądanie pobierania, odpowiedź otrzymuje response.type z „basic”, „cors” lub „opaque”. Te types pokazują, skąd pochodzi zasób, i można ich użyć do określić sposób postępowania z obiektem odpowiedzi.

Gdy przeglądarka żąda zasobu z tego samego źródła, odpowiedź ma typ basic z ograniczeniami dotyczącymi tego, co możesz wyświetlić.

Jeśli zostanie wysłane żądanie dotyczące zasobu z innego punktu początkowego, które zwróci ten punkt początkowy Nagłówki COR, typ to cors. Odpowiedzi cors są podobne do odpowiedzi basic, ale ograniczają nagłówki, które możesz wyświetlić, do Cache-Control, Content-Language, Content-Type, Expires, Last-Modified i Pragma.

Odpowiedzi opaque pochodzą z innego źródła, które nie zwraca nagłówków CORS. W przypadku nieprzezroczystej odpowiedzi nie będziemy mogli odczytać zwróconych danych ani wyświetlić stanu żądania, co oznacza, że nie będzie można sprawdzić, czy żądanie zostało zrealizowane.

Możesz zdefiniować tryb żądania pobierania, aby rozwiązywanie dotyczyło tylko określonych typów żądań. Możesz ustawić te tryby:

  • same-origin działa tylko w przypadku żądań dotyczących komponentów z tego samego źródła i odrzuca wszystkie pozostałe żądania.
  • cors umożliwia wysyłanie żądań zasobów z tego samego źródła i z innych źródeł, zwraca odpowiednie nagłówki COR.
  • cors-with-forced-preflight wykonuje proces wstępny sprawdź przed wysłaniem jakiejkolwiek prośby.
  • no-cors ma na celu wysyłanie żądań do innych źródeł, które nie mają nagłówków CORS, i zwracanie odpowiedzi opaque, ale jak już powiedzieliśmy, obecnie nie jest to możliwe w ramach globalnego zakresu okna.

Aby zdefiniować tryb, dodaj obiekt opcji jako drugi parametr w żądaniu fetch i zdefiniuj tryb w tym obiekcie:

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

Łańcuch obietnic

Jedną z największych cech obietnic jest możliwość ich połączenia. Dla: fetch(), umożliwia współdzielenie logiki między żądaniami pobierania.

Jeśli korzystasz z interfejsu API JSON, musisz sprawdzić jego stan i przeanalizować JSON dla każdej odpowiedzi. Możesz uprościć kod, definiując stan i analizowanie JSON-a w osobnych funkcjach, które zwracają obietnice, a do obsługi tylko danych końcowych i błędów używać żądania fetch.

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(data => {
    console.log('Request succeeded with JSON response', data);
  }).catch(error => {
    console.log('Request failed', error);
  });

Ten przykład definiuje funkcję status, która sprawdza response.status i zwraca rozwiązaną obietnicę jako Promise.resolve(), lub odrzuconą obietnicę jako Promise.reject() Jest to pierwsza metoda wywoływana w łańcuchu fetch().

Jeśli obietnicę można spełnić, skrypt wywołuje metodę json(), która zwraca drugą obietnicę z wywołania response.json() i tworzy obiekt zawierający przetworzony plik JSON. Jeśli parsowanie się nie powiedzie, obietnica zostanie odrzucona, a wyrażenie catch zostanie wykonane.

Taka struktura umożliwia współdzielenie logiki pomiędzy wszystkimi żądaniami pobierania, dzięki czemu łatwiejszy w obsłudze, odczytywaniu i testowaniu.

Żądanie POST

Czasami aplikacja internetowa musi wywołać interfejs API za pomocą metody POST i umieścić niektóre parametry w treści żądania. Aby to zrobić, ustaw parametry method i body w opcjach fetch():

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

Wysyłanie danych logowania z żądaniem pobierania

Aby wysłać żądanie pobierania z danymi logowania, takimi jak pliki cookie, ustaw wartość parametru credentials na "include":

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