Introduction to fetch()  |  Articles  |  web.dev (2024)

Matt Gaunt

fetch() lets you make network requests similar to XMLHttpRequest (XHR). Themain difference is that the Fetch API uses Promises, which has asimpler API to help you avoid the complicated callbacks in theXMLHttpRequest API.

If you've never usedPromisesbefore, check out Introduction to JavaScript Promises.

Basic Fetch Request

Here's an example implemented with an XMLHttpRequestand then with fetch. We want to request a URL, get a response, and parseit as JSON.

XMLHttpRequest

An XMLHttpRequest needs two listeners to handle the successand error cases, and a call to open() and send().Example from MDN docs.

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

Fetch

Our fetch request looks like this:

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

The fetch() request needs only one call to do the same work as the XHRexample. To process the response, we first check that the response status is200, then parse the response as JSON. The response to a fetch() request is aStream object, which means that afterwe call the json() method, a Promise is returned.The stream occurs asynchronously.

The previous example showed the status of theResponse object, and how toparse the response as JSON. Here's how to handle other metadata you might wantto access, like headers:

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

Response Types

When we make a fetch request, the response will be given a response.typeof "basic","cors" or"opaque".These types show where the resource has come from, and you can use them todetermine how to treat the response object.

When the browser requests a resource on the same origin, the response has abasic type with restrictions on what you can view from the response.

If a request is made for a resource on another origin, and that origin returnsCORs headers, then the type is cors. corsresponses are similar to basic responses, but they restrict the headers youcan view to Cache-Control, Content-Language, Content-Type, Expires,Last-Modified, and Pragma.

opaque responses come from a different origin that doesn't return CORSheaders. With an opaque response we won't be able to read the data returned or view the status of the request, meaning you can't checkwhether the request was successful.

You can define a mode for a fetch request so that only certain request typesresolve. The modes you can set are as follows:

  • same-origin only succeeds for requests for assets on the same origin, andrejects all other requests.
  • cors allows requests for assets on the same origin and other origins thatreturn the appropriate CORs headers.
  • cors-with-forced-preflight performs a preflightcheckbefore making any request.
  • no-cors is intended to make requests to other origins that don't have CORSheaders and result in an opaque response, but as stated , this isn'tpossible in the window global scope at the moment.

To define the mode, add an options object as the second parameter in thefetch request and define the mode in that object:

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

Promise chaining

One of the great features of promises is the ability to chain them together. Forfetch(), this lets you share logic across fetch requests.

If you're working with a JSON API, you need to check the status and parse theJSON for each response. You can simplify your code by defining the status andJSON parsing in separate functions that return promises, and use the fetchrequest to handle only the final data and the error case.

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

This example defines a status function that checks the response.status andreturns either a resolved Promise asPromise.resolve(),or a rejected Promise asPromise.reject().This is the first method called in the fetch() chain.

If the Promise resolves, the script then calls the json() method, whichreturns a second Promise from the response.json() call and creates anobject containing the parsed JSON. If the parsing fails, the Promise isrejected and the catch statement executes.

This structure lets you share the logic across all your fetch requests, makingcode easier to maintain, read and test.

POST Request

Sometimes a web app needs to call an API with a POST method and include someparameters in the body of the request. To do this, set the method and bodyparameters in the fetch() options:

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

Send credentials with a fetch request

To make a fetch request with credentials such as cookies, set the request'scredentials value to "include":

fetch(url, { credentials: 'include'})
Introduction to fetch()  |  Articles  |  web.dev (2024)
Top Articles
Latest Posts
Article information

Author: Domingo Moore

Last Updated:

Views: 5959

Rating: 4.2 / 5 (73 voted)

Reviews: 80% of readers found this page helpful

Author information

Name: Domingo Moore

Birthday: 1997-05-20

Address: 6485 Kohler Route, Antonioton, VT 77375-0299

Phone: +3213869077934

Job: Sales Analyst

Hobby: Kayaking, Roller skating, Cabaret, Rugby, Homebrewing, Creative writing, amateur radio

Introduction: My name is Domingo Moore, I am a attractive, gorgeous, funny, jolly, spotless, nice, fantastic person who loves writing and wants to share my knowledge and understanding with you.