Skip to content
Happy Programming Guide
Start learning
JavaScript

JavaScript Fetch API: Getting Data From the Internet

How to request data with fetch, read a JSON response, send data with POST, handle errors properly, and show a loading state.

fetch asks another server for data and gives you back a promise. It is built into every modern browser — no library needed.

JavaScript
const response = await fetch("https://api.example.com/users");
const users = await response.json();
console.log(users);

Two awaits, because two things take time: getting the response, and reading its body.

A complete example#

JavaScript
async function loadUsers() {
  const list = document.querySelector("#users");
  list.textContent = "Loading…";

  try {
    const response = await fetch("https://api.example.com/users");

    if (!response.ok) {
      throw new Error(`Request failed with status ${response.status}`);
    }

    const users = await response.json();

    list.innerHTML = "";
    for (const user of users) {
      const li = document.createElement("li");
      li.textContent = user.name;
      list.appendChild(li);
    }
  } catch (error) {
    list.textContent = "Could not load users. Please try again.";
    console.error(error);
  }
}

Notice there are three states the user can see: loading, loaded, and failed. Skipping the last two is what makes an app feel broken.

Sending data with POST#

JavaScript
const response = await fetch("https://api.example.com/users", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ name: "Ada", email: "ada@example.com" }),
});

const created = await response.json();

Three things are easy to forget: the method, the Content-Type header, and JSON.stringify around the body. Missing any of them usually produces a 400 from the server.

Reading other response types#

JavaScript
await response.json();   // parsed JSON
await response.text();   // raw text — useful when JSON parsing fails
await response.blob();   // images and files

If response.json() throws “Unexpected token”, read it with .text() instead and look at what actually came back. It is often an HTML error page.

The CORS error#

Sooner or later you will see: “has been blocked by CORS policy”. This is a browser security rule: a site can only read responses from another domain if that domain explicitly allows it.

It is not something you can fix in your JavaScript. Your options are to use an API that permits browser requests, or to make the request from your own server instead.

Cancelling a request#

JavaScript
const controller = new AbortController();

fetch("/api/search?q=abc", { signal: controller.signal });

controller.abort();    // e.g. the user typed again

Useful for search-as-you-type, where an old slow response could otherwise overwrite a newer one.

Questions people ask#

What is the difference between fetch and axios?

Axios is a library that adds conveniences — automatic JSON parsing, throwing on error statuses, request cancellation. fetch is built in and enough for most work.

Where do I put an API key?

Not in browser JavaScript. Anything in your front-end code is visible to anyone who opens DevTools. Keys belong on a server that makes the request for you.

Why does my request work in the browser address bar but not in fetch?

Almost always CORS. Typing a URL is a top-level navigation, which is not subject to the same restriction as a script reading a cross-origin response.

Where to go next#

Try a projectBuild a JavaScript quiz app

Keep reading

Keep going — pick your next guide

The fastest way to improve is to read one guide, then build the thing it describes. Start with the basics, or jump straight to a project.

Ask a question or share what worked

Your email address will not be published. Required fields are marked *