Using the Fetch API

The Fetch API provides a JavaScript interface for making HTTP requests and processing the responses.

Fetch is the modern replacement for XMLHttpRequest : unlike XMLHttpRequest , which uses callbacks, Fetch is promise-based and is integrated with features of the modern web such as service workers and Cross-Origin Resource Sharing (CORS).

With the Fetch API, you make a request by calling fetch() , which is available as a global function in both window and worker contexts. You pass it a Request object or a string containing the URL to fetch, along with an optional argument to configure the request.

The fetch() function returns a Promise which is fulfilled with a Response object representing the server's response. You can then check the request status and extract the body of the response in various formats, including text and JSON, by calling the appropriate method on the response.

Here's a minimal function that uses fetch() to retrieve some JSON data from a server:

async function getData()  const url = "https://example.org/products.json"; try  const response = await fetch(url); if (!response.ok)  throw new Error(`Response status: $response.status>`); > const json = await response.json(); console.log(json); > catch (error)  console.error(error.message); > > 

We declare a string containing the URL and then call fetch() , passing the URL with no extra options.

The fetch() function will reject the promise on some errors, but not if the server responds with an error status like 404 : so we also check the response status and throw if it is not OK.

Otherwise, we fetch the response body content as JSON by calling the json() method of Response , and log one of its values. Note that like fetch() itself, json() is asynchronous, as are all the other methods to access the response body content.

In the rest of this page we'll look in more detail at the different stages of this process.

Making a request

To make a request, call fetch() , passing in:

  1. a definition of the resource to fetch. This can be any one of:
  2. optionally, an object containing options to configure the request.

In this section we'll look at some of the most commonly-used options. To read about all the options that can be given, see the fetch() reference page.

Setting the method

By default, fetch() makes a GET request, but you can use the method option to use a different request method:

const response = await fetch("https://example.org/post",  method: "POST", // . >); 

If the mode option is set to no-cors , then method must be one of GET , POST or HEAD .

Setting a body

The request body is the payload of the request: it's the thing the client is sending to the server. You cannot include a body with GET requests, but it's useful for requests that send content to the server, such as POST or PUT requests. For example, if you want to upload a file to the server, you might make a POST request and include the file as the request body.

To set a request body, pass it as the body option:

const response = await fetch("https://example.org/post",  body: JSON.stringify( username: "example" >), // . >); 

You can supply the body as an instance of any of the following types:

Note that just like response bodies, request bodies are streams, and making the request reads the stream, so if a request contains a body, you can't make it twice:

const request = new Request("https://example.org/post",  method: "POST", body: JSON.stringify( username: "example" >), >); const response1 = await fetch(request); console.log(response1.status); // Will throw: "Body has already been consumed." const response2 = await fetch(request); console.log(response2.status); 

Instead, you would need to create a clone of the request before sending it:

const request1 = new Request("https://example.org/post",  method: "POST", body: JSON.stringify( username: "example" >), >); const request2 = request1.clone(); const response1 = await fetch(request1); console.log(response1.status); const response2 = await fetch(request2); console.log(response2.status); 

Setting headers

Request headers give the server information about the request: for example, the Content-Type header tells the server the format of the request's body. Many headers are set automatically by the browser and can't be set by a script: these are called Forbidden header names.

To set request headers, assign them to the headers option.

You can pass an object literal here containing header-name: header-value properties:

const response = await fetch("https://example.org/post",  headers:  "Content-Type": "application/json", >, // . >); 

Alternatively, you can construct a Headers object, add headers to that object using Headers.append() , then assign the Headers object to the headers option:

const myHeaders = new Headers(); myHeaders.append("Content-Type", "application/json"); const response = await fetch("https://example.org/post",  headers: myHeaders, // . >); 

If the mode option is set to no-cors , you can only set CORS-safelisted request headers.

Making POST requests

We can combine the method , body , and headers options to make a POST request:

const myHeaders = new Headers(); myHeaders.append("Content-Type", "application/json"); const response = await fetch("https://example.org/post",  method: "POST", body: JSON.stringify( username: "example" >), headers: myHeaders, >); 

Making cross-origin requests

Whether a request can be made cross-origin or not is determined by the value of the mode option. This may take one of three values: cors , no-cors , or same-origin .