Using the Fetch API - Web APIs | MDN (2024)

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:

js

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:
    • a string containing the URL
    • an object, such an instance of URL, which has a stringifier that produces a string containing the URL
    • a Request instance
  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:

js

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:

js

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:

  • a string
  • ArrayBuffer
  • TypedArray
  • DataView
  • Blob
  • File
  • URLSearchParams
  • FormData

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:

js

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:

js

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

See Locked and disturbed streams for more information.

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:

js

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:

js

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:

js

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.

  • By default, mode is set to cors, meaning that if the request is cross-origin then it will use the Cross-Origin Resource Sharing (CORS) mechanism. This means that:
    • if the request is a simple request, then the request will always be sent, but the server must respond with the correct Access-Control-Allow-Origin header or the browser will not share the response with the caller.
    • if the request is not a simple request, then the browser will send a preflighted request to check that the server understands CORS and allows the request, and the real request will not be sent unless the server responds to the preflighted request with the appropriate CORS headers.
  • Setting mode to same-origin disallows cross-origin requests completely.
  • Setting mode to no-cors means the request must be a simple request, which restricts the headers that may be set, and restricts methods to GET, HEAD, and POST.

Including credentials

Credentials are cookies, TLS client certificates, or authentication headers containing a username and password.

To control whether or not the browser sends credentials, as well as whether the browser respects any Set-Cookie response headers, set the credentials option, which can take one of the following three values:

  • omit: never send credentials in the request or include credentials in the response.
  • same-origin (the default): only send and include credentials for same-origin requests.
  • include: always include credentials, even cross-origin.

Note that if a cookie's SameSite attribute is set to Strict or Lax, then the cookie will not be sent cross-site, even if credentials is set to include.

Including credentials in cross-origin requests can make a site vulnerable to CSRF attacks, so even if credentials is set to include, the server must also agree to their inclusion by including the Access-Control-Allow-Credentials header in its response. Additionally, in this situation the server must explicitly specify the client's origin in the Access-Control-Allow-Origin response header (that is, * is not allowed).

This means that if credentials is set to include and the request is cross-origin, then:

  • If the request is a simple request, then the request will be sent with credentials, but the server must set the Access-Control-Allow-Credentials and Access-Control-Allow-Origin response headers, or the browser will return a network error to the caller. If the server does set the correct headers, then the response, including credentials, will be delivered to the caller.
  • If the request is not a simple request, then the browser will send a preflighted request without credentials, and the server must set the Access-Control-Allow-Credentials and Access-Control-Allow-Origin response headers, or the browser will return a network error to the caller. If the server does set the correct headers, then the browser will follow up with the real request, including credentials, and will deliver the real response, including credentials, to the caller.

Creating a Request object

The Request() constructor takes the same arguments as fetch() itself. This means that instead of passing options into fetch(), you can pass the same options to the Request() constructor, and then pass that object to fetch().

For example, we can make a POST request by passing options into fetch() using code like this:

js

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

However, we could rewrite this to pass the same arguments to the Request() constructor:

js

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

This also means that you can create a request from another request, while changing some of its properties using the second argument:

js

async function post(request) { try { const response = await fetch(request); const result = await response.json(); console.log("Success:", result); } catch (error) { console.error("Error:", error); }}const request1 = new Request("https://example.org/post", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ username: "example1" }),});const request2 = new Request(request1, { body: JSON.stringify({ username: "example2" }),});post(request1);post(request2);

Canceling a request

To make a request cancelable, create an AbortController, and assign its AbortSignal to the request's signal property.

To cancel the request, call the controller's abort() method. The fetch() call will reject the promise with an AbortError exception.

js

const controller = new AbortController();const fetchButton = document.querySelector("#fetch");fetchButton.addEventListener("click", async () => { try { console.log("Starting fetch"); const response = await fetch("https://example.org/get", { signal: controller.signal, }); console.log(`Response: ${response.status}`); } catch (e) { console.error(`Error: ${e}`); }});const cancelButton = document.querySelector("#cancel");cancelButton.addEventListener("click", () => { controller.abort(); console.log("Canceled fetch");});

If the request is aborted after the fetch() call has been fulfilled but before the response body has been read, then attempting to read the response body will reject with an AbortError exception.

js

async function get() { const controller = new AbortController(); const request = new Request("https://example.org/get", { signal: controller.signal, }); const response = await fetch(request); controller.abort(); // The next line will throw `AbortError` const text = await response.text(); console.log(text);}

Handling the response

As soon as the browser has received the response status and headers from the server (and potentially before the response body itself has been received), the promise returned by fetch() is fulfilled with a Response object.

Checking response status

The promise returned by fetch() will reject on some errors, such as a network error or a bad scheme. However, if the server responds with an error like 404, then fetch() fulfills with a Response, so we have to check the status before we can read the response body.

The Response.status property tells us the numerical status code, and the Response.ok property returns true if the status is in the 200 range.

A common pattern is to check the value of ok and throw if it is false:

js

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}`); } // ... } catch (error) { console.error(error.message); }}

Checking the response type

Responses have a type property that can be one of the following:

  • basic: the request was a same-origin request.
  • cors: the request was a cross-origin CORS request.
  • opaque: the request was a cross-origin simple request made with the no-cors mode.
  • opaqueredirect: the request set the redirect option to manual, and the server returned a redirect status.

The type determines the possible contents of the response, as follows:

  • Basic responses exclude response headers from the Forbidden response header name list.
  • CORS responses include only response headers from the CORS-safelisted response header list.
  • Opaque responses and opaque redirect responses have a status of 0, an empty header list, and a null body.

Checking headers

Just like the request, the response has a headers property which is a Headers object, and this contains any response headers that are exposed to scripts, subject to the exclusions made based on the response type.

A common use case for this is to check the content type before trying to read the body:

js

async function fetchJSON(request) { try { const response = await fetch(request); const contentType = response.headers.get("content-type"); if (!contentType || !contentType.includes("application/json")) { throw new TypeError("Oops, we haven't got JSON!"); } // Otherwise, we can read the body as JSON } catch (error) { console.error("Error:", error); }}

Reading the response body

The Response interface provides a number of methods to retrieve the entire body contents in a variety of different formats:

  • Response.arrayBuffer()
  • Response.blob()
  • Response.formData()
  • Response.json()
  • Response.text()

These are all asynchronous methods, returning a Promise which will be fulfilled with the body content.

In this example, we fetch an image and read it as a Blob, which we can then use to create an object URL:

js

const image = document.querySelector("img");const url = "flowers.jpg";async function setImage() { try { const response = await fetch(url); if (!response.ok) { throw new Error(`Response status: ${response.status}`); } const blob = await response.blob(); const objectURL = URL.createObjectURL(blob); image.src = objectURL; } catch (e) { console.error(e); }}

The method will throw an exception if the response body is not in the appropriate format: for example, if you call json() on a response that can't be parsed as JSON.

Streaming the response body

Request and response bodies are actually ReadableStream objects, and whenever you read them, you're streaming the content. This is good for memory efficiency, because the browser doesn't have to buffer the entire response in memory before the caller retrieves it using a method like json().

This also means that the caller can process the content incrementally as it is received.

For example, consider a GET request that fetches a large text file and processes it in some way, or displays it to the user:

js

const url = "https://www.example.org/a-large-file.txt";async function fetchText(url) { try { const response = await fetch(url); if (!response.ok) { throw new Error(`Response status: ${response.status}`); } const text = await response.text(); console.log(text); } catch (e) { console.error(e); }}

If we use Response.text(), as above, we must wait until the whole file has been received before we can process any of it.

If we stream the response instead, we can process chunks of the body as they are received from the network:

js

const url = "https://www.example.org/a-large-file.txt";async function fetchTextAsStream(url) { try { const response = await fetch(url); if (!response.ok) { throw new Error(`Response status: ${response.status}`); } const stream = response.body.pipeThrough(new TextDecoderStream()); for await (const value of stream) { console.log(value); } } catch (e) { console.error(e); }}

In this example, we iterate asynchronously over the stream, processing each chunk as it arrives.

Note that when you access the body directly like this, you get the raw bytes of the response and must transform it yourself. In this case we call ReadableStream.pipeThrough() to pipe the response through a TextDecoderStream, which decodes the UTF-8-encoded body data as text.

Processing a text file line by line

In the example below, we fetch a text resource and process it line by line, using a regular expression to look for line endings. For simplicity, we assume the text is UTF-8, and don't handle fetch errors:

js

async function* makeTextFileLineIterator(fileURL) { const response = await fetch(fileURL); const reader = response.body.pipeThrough(new TextDecoderStream()).getReader(); let { value: chunk, done: readerDone } = await reader.read(); chunk = chunk || ""; const newline = /\r?\n/gm; let startIndex = 0; let result; while (true) { const result = newline.exec(chunk); if (!result) { if (readerDone) break; const remainder = chunk.substr(startIndex); ({ value: chunk, done: readerDone } = await reader.read()); chunk = remainder + (chunk || ""); startIndex = newline.lastIndex = 0; continue; } yield chunk.substring(startIndex, result.index); startIndex = newline.lastIndex; } if (startIndex < chunk.length) { // Last line didn't end in a newline char yield chunk.substring(startIndex); }}async function run(urlOfFile) { for await (const line of makeTextFileLineIterator(urlOfFile)) { processLine(line); }}function processLine(line) { console.log(line);}run("https://www.example.org/a-large-file.txt");

Locked and disturbed streams

The consequences of request and response bodies being streams are that:

  • if a reader has been attached to a stream using ReadableStream.getReader(), then the stream is locked, and nothing else can read the stream.
  • if any content has been read from the stream, then the stream is disturbed, and nothing else can read from the stream.

This means it's not possible to read the same response (or request) body more than once:

js

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 json1 = await response.json(); const json2 = await response.json(); // will throw } catch (error) { console.error(error.message); }}

If you do need to read the body more than once, you must call Response.clone() before reading the body:

js

async function getData() { const url = "https://example.org/products.json"; try { const response1 = await fetch(url); if (!response1.ok) { throw new Error(`Response status: ${response1.status}`); } const response2 = response1.clone(); const json1 = await response1.json(); const json2 = await response2.json(); } catch (error) { console.error(error.message); }}

This is a common pattern when implementing an offline cache with service workers. The service worker wants to return the response to the app, but also to cache the response. So it clones the response, returns the original, and caches the clone:

js

async function cacheFirst(request) { const cachedResponse = await caches.match(request); if (cachedResponse) { return cachedResponse; } try { const networkResponse = await fetch(request); if (networkResponse.ok) { const cache = await caches.open("MyCache_1"); cache.put(request, networkResponse.clone()); } return networkResponse; } catch (error) { return Response.error(); }}self.addEventListener("fetch", (event) => { if (precachedResources.includes(url.pathname)) { event.respondWith(cacheFirst(event.request)); }});

See also

Using the Fetch API - Web APIs | MDN (2024)

FAQs

How do I fetch a Web API? ›

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.

What is the use of fetch API? ›

The Fetch API is a modern JavaScript interface for making network requests, primarily designed to replace the older XMLHttpRequest. It provides a more straightforward and flexible way to handle HTTP requests, making it easier for developers to work with APIs and fetch data from servers.

How to use data fetched from API? ›

To fetch data using the Fetch API in JavaScript, you use the fetch() function with the URL of the resource you want to retrieve. By default, the fetch() function makes a GET request.

How do I create an API to fetch data from my website? ›

In order to turn a website into an API, you first need a web scraper. A web scraper is a tool that automates the process of extracting data from websites, in the form of HTML code, and converts it into a usable structured format – either in a spreadsheet, like with Visualping's Google Sheets integration, or in an API.

What is the difference between fetch API and REST API? ›

Some of the differences include: Fetch is a function which takes a REST API url in its call. REST APIs can accept headers like for Authentication but Fetch call be called by any javascript in the browser and in fact passes these headers while calling the REST APIs.

How to use Fetch for beginners? ›

  1. Step 1 | Download the app. You can't get free gift cards from Fetch if you don't have the app. Go to the (Android) Google Play Store or the (Apple) iOS Store to install the app on your mobile phone or tablet.
  2. Step 2 | Snap all your receipts. Fetch makes scanning receipts quick and easy. ...
  3. Step 3 | Redeem your points. Fetch.
Sep 21, 2022

Why would you use fetch? ›

Fetch is a rewards app that allows you to gain points simply by uploading pictures of your shopping receipts. These points can then be traded in for gift cards from a variety of US-based retailers.

Why use fetch instead of get? ›

Simple Data Retrieval: Use GET for straightforward queries where caching and idempotence are beneficial. Complex Operations: Use FETCH when you need to send data (e.g., JSON payloads) or require detailed control over the request.

What are the advantages of fetch API? ›

Fetch API features and pros:
  • more pleasant simpler API. ...
  • supports streaming, response. ...
  • has cache control support (default, no-store, reload, no-cache, force-cache, only-if-cached)
  • has better control of cross-origin (same-origin, cors, no-cors) and credentialed requests (omit, same-origin, include)

How to fetch data from a website? ›

All in all, here are the main stages of how to extract data from the web:
  1. Decide the type of data you want to fetch and process.
  2. Find where the data is displayed and build a scraping path.
  3. Import and install the required prerequisites.
  4. Write a data extraction script and implement it.
Feb 7, 2024

Why use axios instead of fetch? ›

Fetch is simpler syntactically but Axios includes more built-in capabilities. If you need these additional features or wider browser support, Axios may be a better choice. However, Fetch can be useful for basic HTTP requests in newer browser environments.

How to fetch data in REST API? ›

To retrieve API data using a REST client, follow these steps:
  1. Choose a REST client tool or library suitable for your project's requirements and language.
  2. Set the HTTP method (usually GET for retrieving data) and provide the API endpoint URL.
  3. Configure any required headers, such as API keys or authentication tokens.
Jul 22, 2024

How do I use an API in my website? ›

The typical steps involved in using an API are:
  1. Look for an API that will meet your needs.
  2. Understand the API terms for using.
  3. Read the API documentation so you can test the API.
  4. Request an API key.
  5. Using the API documentation to make an API request.
  6. Interpret the API response to see if it meets your needs.
Nov 30, 2023

How does Fetch API work? ›

The Fetch API uses Request and Response objects (and other things involved with network requests), as well as related concepts such as CORS and the HTTP Origin header semantics. For making a request and fetching a resource, use the fetch() method. It is a global method in both Window and Worker contexts.

How do I get data from a Web API? ›

  1. Register a Web API.
  2. Create a JSON parser.
  3. Create a JSON Dataset.
  4. Create a Knowledge Graph.
  5. Create a Transformation.
  6. Create a Workflow.

How do I access Web API? ›

You can use any web browser to access an API by passing in the endpoint or url into the search bar or url input section in every browser. This involves the use of browsers like Chrome,Firefox,Edge,Brave etc.

How do I get a website API? ›

To find an API key, you usually need to visit the website or platform that offers the API you want to use. The process can vary depending on the specific API provider, but you typically need to sign up for an account, create a project or application, and then generate an API key within that project.

How to retrieve data from Web API? ›

  1. 1 Register a Web API. Click the Create button (top right) in the data integration workspace and select the type REST request. ...
  2. 2 Create a JSON parser. ...
  3. 3 Create a JSON Dataset. ...
  4. 4 Create a Knowledge Graph. ...
  5. 5 Create a Transformation. ...
  6. 6 Create a Workflow.

How do I fetch data from a Web service? ›

Process
  1. Create a source HTTP Connection.
  2. Create a destination Connection for the relational database and test it.
  3. Create a Format for the payload returned by the web service, most likely JSON or XML.
  4. Link Connection and Format and test the response for the web service in the EXPLORER .
Feb 21, 2024

Top Articles
Why You Should Notify Your Credit Card Company When You Travel
Effective Ways to Authenticate Users
Fernald Gun And Knife Show
Netronline Taxes
Katie Nickolaou Leaving
Kmart near me - Perth, WA
Mcfarland Usa 123Movies
Insidious 5 Showtimes Near Cinemark Tinseltown 290 And Xd
What Happened To Dr Ray On Dr Pol
Poplar | Genus, Description, Major Species, & Facts
Flights to Miami (MIA)
Tugboat Information
Snowflake Activity Congruent Triangles Answers
Palace Pizza Joplin
5808 W 110Th St Overland Park Ks 66211 Directions
使用 RHEL 8 时的注意事项 | Red Hat Product Documentation
Wausau Obits Legacy
Fort Mccoy Fire Map
Transactions (zipForm Edition) | Lone Wolf | Real Estate Forms Software
Ppm Claims Amynta
Marion City Wide Garage Sale 2023
Ou Class Nav
Directions To Nearest T Mobile Store
Craigslist Panama City Beach Fl Pets
FAQ's - KidCheck
Ou Football Brainiacs
Kuttymovies. Com
Paradise Point Animal Hospital With Veterinarians On-The-Go
Ts Modesto
Kiddie Jungle Parma
Publix Daily Soup Menu
Myhrconnect Kp
Muziq Najm
How are you feeling? Vocabulary & expressions to answer this common question!
Jason Brewer Leaving Fox 25
Craigslist Freeport Illinois
Dispensaries Open On Christmas 2022
manhattan cars & trucks - by owner - craigslist
Achieving and Maintaining 10% Body Fat
Bunkr Public Albums
Windshield Repair & Auto Glass Replacement in Texas| Safelite
Mathews Vertix Mod Chart
Expendables 4 Showtimes Near Malco Tupelo Commons Cinema Grill
'The Nun II' Ending Explained: Does the Immortal Valak Die This Time?
Deezy Jamaican Food
Fluffy Jacket Walmart
Keci News
Devotion Showtimes Near Showplace Icon At Valley Fair
Bumgarner Funeral Home Troy Nc Obituaries
Obituary Roger Schaefer Update 2020
Latest Posts
Article information

Author: Reed Wilderman

Last Updated:

Views: 6097

Rating: 4.1 / 5 (52 voted)

Reviews: 83% of readers found this page helpful

Author information

Name: Reed Wilderman

Birthday: 1992-06-14

Address: 998 Estell Village, Lake Oscarberg, SD 48713-6877

Phone: +21813267449721

Job: Technology Engineer

Hobby: Swimming, Do it yourself, Beekeeping, Lapidary, Cosplaying, Hiking, Graffiti

Introduction: My name is Reed Wilderman, I am a faithful, bright, lucky, adventurous, lively, rich, vast person who loves writing and wants to share my knowledge and understanding with you.