Jak používat rozhraní Fetch API k vytváření požadavků HTTP v JavaScriptu

Fetch API je JavaScript API založené na slibech pro vytváření asynchronních HTTP požadavků v prohlížeči podobných XMLHttpRequest (XHR). Na rozdíl od XHR je to jednoduché a čisté API, které využívá sliby k poskytování výkonnější a flexibilnější sady funkcí pro načítání zdrojů ze serveru.

Fetch API je nyní do značné míry standardizováno a je podporováno všemi moderními prohlížeči kromě IE. Pokud potřebujete podporovat všechny prohlížeče včetně IE, přidejte do svého projektu polyfill vydaný GitHubem.

Základní použití API

Použití Fetch API je opravdu jednoduché. Stačí předat adresu URL, cestu ke zdroji, který chcete načíst, do fetch() metoda:

fetch('/js/users.json')
    .then(response => {
        // handle response data
    })
    .catch(err => {
        // handle errors
    });

Cestu pro zdroj, který chceme získat, předáme jako parametr do fetch() . Vrátí příslib, který předá odpověď na then() když je splněno. catch() metoda zachycuje chyby, pokud se požadavek nepodaří dokončit kvůli selhání sítě nebo z jakéhokoli jiného důvodu.

Žádost ZÍSKAT

Ve výchozím nastavení používá rozhraní Fetch API metodu GET pro asynchronní požadavky. Použijme rozhraní Reqres REST API k získání seznamu uživatelů pomocí požadavku GET:

fetch('https://reqres.in/api/users')
    .then(res => res.json())
    .then(res => {
        res.data.map(user => {
            console.log(`${user.id}: ${user.first_name} ${user.last_name}`);
        });
    });

Výše uvedený požadavek vytiskne na konzoli následující:

1: George Bluth
2: Janet Weaver
3: Emma Wong

Volání fetch() metoda vrací slib. Odpověď vrácená příslibem je objekt streamu, což znamená, že když zavoláme json() způsob, vrátí další příslib. Zavolejte na číslo json() metoda označuje, že očekáváme odpověď JSON. Pokud očekáváte odpověď XML, měli byste použít text() metoda.

Požadavek POST

Stejně jako Axios nám také Fetch umožňuje v požadavku použít jakoukoli jinou metodu HTTP:POST, PUT, DELETE, HEAD a OPTIONS. Vše, co musíte udělat, je nastavit method a body parametry v fetch() možnosti:

const user = {
    first_name: 'John',
    last_name: 'Lilly',
    job_title: 'Software Engineer'
};

const options = {
    method: 'POST',
    body: JSON.stringify(user),
    headers: {
        'Content-Type': 'application/json'
    }
}

fetch('https://reqres.in/api/users', options)
    .then(res => res.json())
    .then(res => console.log(res));

Reqres API nám posílá data těla zpět s připojeným ID a vytvořeným časovým razítkem:

{  
   "first_name":"John",
   "last_name":"Lilly",
   "job_title":"Software Engineer",
   "id":"482",
   "createdAt":"2019-05-12T15:09:13.140Z"
}

SMAZAT požadavek

Požadavek DELETE vypadá velmi podobně jako požadavek POST kromě body není vyžadováno:

const options = {
    method: 'DELETE',
    headers: {
        'Content-Type': 'application/json'
    }
}

fetch('https://reqres.in/api/users/2', options)
    .then(res => {
        if (res.ok) {
            return Promise.resolve('User deleted.');
        } else {
            return Promise.reject('An error occurred.');
        }
    })
    .then(res => console.log(res));

Zpracování chyb

Od fetch() metoda vrací slib, ošetření chyb je snadné. Můžeme použít catch() metoda příslibu zachytit jakoukoli chybu, která je vyvolána během provádění požadavku. Pokud však požadavek zasáhne server a vrátí se, nebude vyvolána žádná chyba, bez ohledu na to, jakou odpověď server vrátil. Příslib vrácený fetch() neodmítne chyby HTTP, i když je kód odpovědi HTTP 404 nebo 500.

Naštěstí můžete použít ok vlastnost objektu odpovědi pro kontrolu, zda byl požadavek úspěšný nebo ne:

fetch('https://reqres.in/api/users/22') // 404 Error
    .then(res => {
        if (res.ok) {
            return res.json();
        } else {
            return Promise.reject(res.status);
        }
    })
    .then(res => console.log(res))
    .catch(err => console.log(`Error with message: ${err}`));

Záhlaví požadavků

Záhlaví požadavku (například Accept , Content-Type , User-Agent , Referer atd.) jsou nezbytnou součástí každého požadavku HTTP. Headers rozhraní Fetch API objekt nám umožňuje nastavit, odstranit nebo načíst záhlaví požadavků HTTP.

Můžeme vytvořit objekt záhlaví pomocí Headers() konstruktor a poté použijte append , has , get , set a delete metody pro úpravu záhlaví požadavků:

// create an empty `Headers` object 
const headers = new Headers();

// add headers
headers.append('Content-Type', 'text/plain');
headers.append('Accept', 'application/json');

// add custom headers
headers.append('X-AT-Platform', 'Desktop');
headers.append('X-AT-Source', 'Google Search');

// check if header exists
headers.has('Accept'); // true

// get headers
headers.get('Accept'); // application/json
headers.get('X-AT-Source'); // Google Search

// update header value
headers.set('Content-Type', 'application/json');

// remove headers
headers.delete('Content-Type');
headers.delete('X-AT-Platform');

Můžeme také předat konstruktoru pole polí nebo objektový literál, aby se vytvořil objekt záhlaví:

// passing an object literal
const headers = new Headers({
    'Content-Type': 'application/json',
    'Accept': 'application/json'
});

// OR

// passing an array of arrays
const headers = new Headers([
    ['Content-Type', 'application/json'],
    ['Accept', 'application/json']
]);

Chcete-li k požadavku přidat záhlaví, jednoduše vytvořte Request instance a předejte ji fetch() metoda namísto adresy URL:

const request = new Request('https://reqres.in/api/users', {
    headers: headers
});

fetch(request)
    .then(res => res.json())
    .then(json => console.log(json))
    .catch(err => console.error('Error:', err));

Objekt požadavku

Request objekt představuje požadavek na zdroj a lze jej vytvořit voláním Request() konstruktor:

const request = new Request('https://reqres.in/api/users');

Request objekt také přijímá objekt URL:

const url = new URL('https://reqres.in/api/users');
const request = new Request(url);

Předáním Request objekt fetch() , můžete snadno přizpůsobit vlastnosti požadavku:

  • method — Metoda HTTP jako GET , POST , PUT , DELETE , HEAD
  • url — Adresa URL požadavku, řetězec nebo objekt URL
  • headersHeaders objekt pro hlavičky požadavků
  • referrer — referrer požadavku (např. client )
  • mode — Režim pro požadavky napříč původem (např. cors , no-cors , same-origin )
  • credentials — Měly by s požadavkem odpovídat soubory cookie a hlavičky HTTP-Authorization? (např. include , omit , same-origin )
  • redirect — Režim přesměrování požadavku (např. follow , error , manual )
  • integrity — Hodnota integrity podzdroje požadavku
  • cache — Režim mezipaměti požadavku (např. default , reload , no-cache )

Vytvořme Request objekt s některými přizpůsobenými vlastnostmi a obsahem těla pro vytvoření požadavku POST:

const user = {
    first_name: 'John',
    last_name: 'Lilly',
    job_title: 'Software Engineer'
};

const headers = new Headers({
    'Content-Type': 'application/json',
    'Accept': 'application/json'
});

const request = new Request('https://reqres.in/api/users', {
    method: 'POST',
    headers: headers,
    redirect: 'follow',
    mode: 'cors',
    body: JSON.stringify(user)
});

fetch(request)
    .then(res => res.json())
    .then(json => console.log(json))
    .catch(err => console.error('Error:', err));

Je vyžadován pouze první argument, adresa URL. Všechny tyto vlastnosti jsou pouze pro čtení, což znamená, že po vytvoření objektu požadavku nemůžete změnit jejich hodnotu. Rozhraní Fetch API striktně nevyžaduje Request objekt. Objektový literál předáme fetch() metoda, funguje jako Request objekt:

fetch('https://reqres.in/api/users', {
    method: 'POST',
    headers: headers,
    redirect: 'follow',
    mode: 'cors',
    body: JSON.stringify(user)
}).then(res => res.json())
    .then(json => console.log(json))
    .catch(err => console.error('Error:', err));

Objekt odpovědi

Response objekt vrácený fetch() metoda obsahuje informace o požadavku a odpovědi na síťový požadavek včetně záhlaví, stavového kódu a stavové zprávy:

fetch('https://reqres.in/api/users')
    .then(res => {
        // get response headers
        console.log(res.headers.get('content-type'));
        console.log(res.headers.get('expires'));

        // HTTP response status code 
        console.log(res.status);

        // shorthand for `status` between 200 and 299 
        console.log(res.ok); 

        // status message of the response e.g. `OK`
        console.log(res.statusText);

        // check if there was a redirect
        console.log(res.redirected);

        // get the response type (e.g., `basic`, `cors`)
        console.log(res.type);

        // the full path of the resource
        console.log(res.url);
    });

Tělo odpovědi je přístupné pomocí následujících metod:

  • json() vrátí tělo jako objekt JSON
  • text() vrátí tělo jako řetězec
  • blob() vrátí tělo jako objekt Blob
  • formData() vrátí tělo jako objekt FormData
  • arrayBuffer() vrátí tělo jako objekt ArrayBuffer

Všechny tyto metody vracejí slib. Zde je příklad text() metoda:

fetch('https://reqres.in/api/unknown/2')
    .then(res => res.text())
    .then(res => console.log(res));

Výstupem výše uvedeného síťového volání bude řetězec JSON:

'{"data":{"id":2,"name":"fuchsia rose","year":2001,"color":"#C74375","pantone_value":"17-2031"}}'

Načítání a soubory cookie

Ve výchozím nastavení, když použijete Fetch k získání prostředku, požadavek neobsahuje přihlašovací údaje, jako jsou soubory cookie. Pokud chcete posílat soubory cookie, musíte výslovně povolit přihlašovací údaje, jak je uvedeno níže:

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

Načíst a asynchronně/vyčkat

Vzhledem k tomu, že Fetch je API založené na slibech, můžeme jít ještě o krok dále a použít nejnovější syntaxi ES2017 async/await, aby byl náš kód ještě jednodušší a synchronně vypadající:

const fetchUsers = async () => {
    try {
        const res = await fetch('https://reqres.in/api/users');
        if (!res.ok) {
            throw new Error(res.status);
        }
        const data = await res.json();
        console.log(data);
    } catch (error) {
        console.log(error);
    }
}

fetchUsers();

Závěr

To je vše pro úvod do JavaScript Fetch API. Je to obrovské zlepšení oproti XMLHttpRequest s jednoduchým, elegantním a snadno použitelným rozhraním. Fetch funguje skvěle pro načítání síťových zdrojů (dokonce i přes síť uvnitř servisních pracovníků). Rozhraní Fetch API podporují všechny moderní prohlížeče, takže pokud nechcete podporovat IE, není třeba používat žádné polyfill.