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.
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 odpowiedziopaque
, 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'
})