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 Promises, który ma prostszy interfejs API, który pomaga uniknąć skomplikowanych wywołań zwrotnych w interfejsie XMLHttpRequest API.

Obsługa przeglądarek

  • 42
  • 14
  • 39
  • 10.1

Źródło

Jeśli nie znasz jeszcze pozycji Promises, zapoznaj się z artykułem Wprowadzenie do obietnic związanych z JavaScriptem.

Podstawowe żądanie pobierania

Oto przykład zaimplementowanego za pomocą funkcji XMLHttpRequest i fetch. Chcemy wysłać żądanie adresu URL, otrzymać odpowiedź i przeanalizować go jako plik JSON.

XMLHttpRequest

Element XMLHttpRequest wymaga 2 detektorów do obsługi przypadków powodzenia i błędów oraz wywołania open() i send(). Przykład z dokumentacji 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();

Pobierz

Żądanie pobrania wygląda tak:

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);
  });

Żądanie fetch() wymaga tylko 1 wywołania, aby wykonać to samo działanie co przykład w XHR. Aby przetworzyć odpowiedź, najpierw sprawdzamy, czy jej stan to 200, a potem analizujemy ją w formacie JSON. Odpowiedź na żądanie fetch() jest obiektem Stream, co oznacza, że po wywołaniu metody json() zwracana jest obietnica. Strumień ma miejsce asynchronicznie.

Metadane odpowiedzi

W poprzednim przykładzie pokazaliśmy stan obiektu Response i sposób analizowania odpowiedzi jako pliku JSON. Oto jak obsługiwać inne metadane, do których chcesz mieć dostęp, np. nagłówki:

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);
});

Typy odpowiedzi

Po wysłaniu żądania pobierania odpowiedź otrzymuje response.typebasic”, „cors” lub „opaque”. Te types pokazują, skąd pochodzi zasób. Możesz ich użyć do określenia, jak traktować obiekt odpowiedzi.

Gdy przeglądarka wysyła żądanie zasobu w tym samym źródle, odpowiedź ma typ basic z ograniczeniami dotyczącymi tego, co można zobaczyć w odpowiedzi.

Jeśli zostanie wysłane żądanie zasobu z innego źródła, które zwróci nagłówki COR, typ to cors. corsOdpowiedzi są podobne do odpowiedzi typu basic, ale ograniczają wyświetlane nagłówki 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 nieprzejrzystej odpowiedzi nie możemy odczytać zwróconych danych ani sprawdzić stanu żądania, co oznacza, że nie można sprawdzić, czy żądanie zostało zrealizowane.

Możesz zdefiniować tryb żądania pobierania, tak aby rozpoznawane były tylko niektóre typy żądań. Możesz wybrać te tryby:

  • Działanie same-origin zostaje zrealizowane tylko w przypadku żądań zasobów z tego samego źródła, a wszystkie pozostałe żądania są odrzucane.
  • cors zezwala na żądania dotyczące zasobów z tego samego źródła i innych źródeł, które zwracają odpowiednie nagłówki COR.
  • Przed wysłaniem jakiegokolwiek żądania cors-with-forced-preflight wykonuje kontrolę wstępną.
  • Funkcja no-cors służy do wysyłania żądań do innych źródeł bez nagłówków CORS i generujących odpowiedź opaque. Jak wspomnieliśmy, nie jest to obecnie możliwe w globalnym zakresie okna.

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

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)
    });

Łańcuch obietnic

Jedną z największych zalet przewidywań jest łączenie ich ze sobą. W przypadku fetch() umożliwia to współdzielenie logiki między żądaniami pobierania.

Jeśli korzystasz z interfejsu API JSON, musisz sprawdzić stan i przeanalizować JSON dla każdej odpowiedzi. Aby uprościć kod, określ stan i analizę JSON w osobnych funkcjach, które zwracają obietnice, oraz wykorzystaj żądanie pobierania do obsługi tylko danych końcowych i przypadku błędu.

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);
    });

W tym przykładzie zdefiniowano funkcję status, która sprawdza response.status i zwraca rozwiniętą obietnicę jako Promise.resolve() lub odrzuconą obietnicę jako Promise.reject(). Jest to pierwsza metoda wywoływana w łańcuchu fetch().

Jeśli obietnica zostanie rozwiązana, skrypt wywołuje metodę json(), która zwraca drugą obietnicę z wywołania response.json() i tworzy obiekt zawierający przeanalizowany kod JSON. Jeśli analiza się nie powiedzie, obietnica zostanie odrzucona, a instrukcja catch zostanie wykonana.

Ta struktura umożliwia współużytkowanie logiki we wszystkich żądaniach pobierania, co ułatwia obsługę, odczytywanie i testowanie kodu.

Żądanie POST

Czasami aplikacja internetowa musi wywołać interfejs API za pomocą metody POST i umieścić w treści żądania określone parametry. 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(function (data) {
    console.log('Request succeeded with JSON response', data);
    })
    .catch(function (error) {
    console.log('Request failed', error);
    });

Wysyłanie danych logowania za pomocą żądania pobierania

Aby wysłać żądanie pobierania z użyciem danych logowania, takich jak pliki cookie, ustaw wartość credentials żądania na "include":

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