chevron-left chevron-right

[JS] Fetch API – nowy sposób na pobieranie danych z serwera

Przez wiele lat wielu twórców stron internetowych czy też programistów JavaScript korzystało z obiektu XMLHttpRequest aby wykonywać zapytania po dane z własnego serwera bądź z serwisów zewnętrznych. Od pewnego czasu jednak sytuacja uległa pewnej zmianie. Pojawiło się nowe rozwiązanie dające więcej możliwości. Jest to Fetch API.

Czym jest Fetch API?

Fetch API jest narzędziem do komunikowania się z różnymi źródłami danych podobnie jak XMLHttpRequest, ale różnica między nimi sprowadza się do tego, że API korzysta z Promises co pozwala na pisanie ładniejszego kodu JS i uniknięcie tzw. callback hell, a także nie trzeba już pamiętać o tych wszystkich wymaganych rzeczach dotyczących tworzenia requestów jak to ma miejsce w starym standardzie.

Powiązane interfejsy Fetch API

W skład Fetch API wchodzą 2 interfejsy (obiekty JS), które można przekazać podczas wykonywania zapytania do serwera oraz jeden obiekt, który może być zwrócony przy odpowiedzi z serwera.

Headers

Interfejs Headers pozwala tworzyć mapę nagłówków wraz z ich wartościami. Jest to przydatne w przypadku serwerów, które wymagają odpowiednich nagłówków, aby uzyskać dostęp do danych

1
2
3
4
5
6
7
8
9
10
11
// pierwszy sposób tworzenia obiektu Headers
const headers1 = new Headers();
 
myHeaders.append('Content-Type', 'text/plain');
myHeaders.append('X-Siteaccess', 'pl');
 
// drugi sposób tworzenia obiektu Headers
const headers2 = new Headers({
  'Content-Type': 'text/plain',
  'X-Custom-Header': 'pl',
});

Gdy już korzystamy z raz utworzonego obiektu Headers to możemy zarządzać jego składem poprzez zmianę wartości nagłówków, dokładanie nowych nagłówków bądź usuwanie informacji o nich z obiektu.

1
2
3
4
5
6
7
8
9
headers1.set('Content-Type', 'text/html');
headers1.append('X-Custom-Header', 'pierwszy');
headers1.append('X-Custom-Header', 'drugi');
 
console.log(headers1.get('X-Siteaccess')); // 'pl'
console.log(headers1.getAll('X-Custom-Header')); // ['pierwszy', 'drugi']
 
headers1.delete('X-Custom-Header');
console.log(headers1.getAll('X-Custom-Header')); // []

Pełny zestaw informacji na temat tego interfejsu możesz znaleźć na tej stronie.

Request

Podobnie jak interfejs **Headers** może zostać wykorzystany interjfejs Request.

1
const myRequest = new Request('/send-data', {method: 'POST', body: '{"name":"test"}'});

Instancja obiektu **Request** przyjmuje w powyższym przypadku dwa parametry: adres punktu dostępowego do danych oraz obiekt z konfiguracją zapytania. Obiekt z konfiguracją informuje o tym w jaki sposób chcemy przesłać dane oraz jakie dane przesyłamy. Zwróć uwagę na to, że parametr body zawiera zserializowany obiekt JSON, tj. obiekt JSON został przerobiony na string, np. za pomocą JSON.stringify().

Więcej informacji o tym interfejsie znajdziesz tutaj.

Response

Obiekt będący instancją interfejsu Response jest przekazywany jako odpowiedź z serwera. Zawiera wszystkie informacje zwrotne.

Aby zobaczyć jak to wygląda w praktyce przeczytaj poniższe sekcje z przykładami tworzenia zapytań do serwera.

Podobnie jak w przypadku poprzednich interfejsów, więcej na temat możesz przeczytać na dedykowanej stronie.

Jak stworzyć zapytanie do własnego serwera za pomocą Fetch API?

Tworzenie nowych zapytań do serwera jest banalnie proste. Pomijając informacje o interfejsach, które przekazałem wcześniej możemy wykonać zapytanie w następujący sposób:

1
2
3
4
5
6
7
8
9
10
11
12
13
fetch('/api/content/all')  
    .then(function (response) {  
        // response jest instancją interfejsu Response
        if (response.status !== 200) {  
            return Promise.reject('Zapytanie się nie powiodło');  
        }
 
        // zwracamy obiekt typu Promise zwracający dane w postaci JSON
        return response.json();  
    }  
  )  
  .then(this._doSomethingWithJson)
  .catch(this._catchError);

Jeśli nie zdefinujemy inaczej to każde zapytanie wykonane za pomocą fetch() będzie typu GET.

Jak stworzyć zapytanie do zewnętrznego serwisu za pomocą Fetch API?

Ten przykład będzie nieco bardziej zaawansowany. Będzie zawierał przykłady użycia interfejsów wymienionych wcześniej.

1
2
3
4
5
6
7
8
9
10
11
12
13
const headers = new Headers({
    'Content-Type': 'text/plain'
});
 
const request = new Request({
    method: 'POST',
    mode: 'cors',
    headers: headers
});
 
fetch('https://blog.piotrnalepa.pl/api/content/all', request)
    .then(this._handleResponse)
    .catch(this._catchError);

Podsumowanie

To API jest bardzo wygodne w użyciu i znacząco ułatwia pracę z kodem JS. Jeśli należysz do grona osób, które tworzą nowy kod przeznaczony tylko dla najnowszych wersji przeglądarek, to w zasadzie nic Ciebie nie powstrzymuje. W przypadku, gdy z jakiegoś powodu musisz wspierać starsze przeglądarki, to zawsze pozostaje możliwość załadowania dodatkowego helpera JS, który zapewni wsparcie w starszych przeglądarkach.

Wsparcie przeglądarek wygląda następująco:

Wsparcie przeglądarek dla Fetch API - stan na dzień 15.01.2017

Więcej informacji na temat Fetch API znajdziesz na tej stronie.