JavaScript Fetch API Guide: GET, POST, Error Handling, and Real-World Examples

1. Introduction

JavaScript is one of the most widely used programming languages in web development. Among its many features, the Fetch API has gained attention as an important capability for enabling asynchronous communication.

In this article, we explain the Fetch API in detail—from the basics to more advanced usage. By understanding it, you’ll be able to implement data fetching and server communication more smoothly in web applications.

What is asynchronous communication?

Asynchronous communication is a method of exchanging data with a server while continuing other processing without blocking until the communication finishes. This improves user interface responsiveness and makes it easier to handle data without frustration.

For example, when a user clicks a button on a web page to fetch data, other tasks can continue without waiting for the server’s response, greatly improving the user experience.

What is the Fetch API?

The Fetch API is a modern interface for performing asynchronous communication in JavaScript. It was introduced as an alternative to the traditional XMLHttpRequest (XHR), offering concise syntax and flexible configuration.

With this API, you can easily write logic to retrieve data from a server or send data to a server.

In the following sections, we will introduce everything step by step—from basic Fetch API usage to practical, real-world examples.

2. What is the Fetch API?

The Fetch API is the latest standard interface for performing asynchronous communication in JavaScript. In this section, we explain its basic role and how it differs from traditional approaches.

Overview of the Fetch API

The Fetch API is designed to retrieve resources over a network.
This makes it easy for web applications to communicate with servers.

Key features

  • Promise-based: No need to rely on callback functions, allowing you to write more readable code.
  • Concise syntax: Compared to XMLHttpRequest, it can significantly reduce the amount of code.
  • High flexibility: You can customize requests and responses in detail.
  • Modern design: Works well with modern JavaScript features, enabling maintainable code.

Below is a basic example of using the Fetch API.

fetch('https://api.example.com/data')
  .then(response => response.json()) // Convert to JSON
  .then(data => console.log(data))  // Output the data
  .catch(error => console.error('Error:', error)); // Error handling

This code fetches data from the specified URL, converts it to JSON, and displays it in the console. If an error occurs, it prints an error message.

Differences from traditional XMLHttpRequest

The Fetch API is a new approach that replaces the widely used XMLHttpRequest (XHR). The table below compares the two.

FeatureFetch APIXMLHttpRequest
Code simplicityConcise, readable syntaxOften complex with many callbacks
Asynchronous handlingSupports Promises and offers high flexibilityRequires callback functions
Stream processingNative supportRequires additional handling
Working with JSONEasy to handleRequires explicit parsing
Error handlingFlexible and can be centralizedOften becomes complex

As you can see, the Fetch API is attractive because of its concise and modern design. In particular, being Promise-based allows you to write asynchronous logic more naturally.

Summary

The Fetch API is a powerful and easy-to-use tool for asynchronous communication in JavaScript. Because it is simpler to implement than traditional XHR, it has become an essential skill for modern web development.

In the next section, we’ll walk through concrete usage patterns of the Fetch API with code examples.

3. Basic usage of the Fetch API

In this section, we explain the basic usage of the Fetch API with concrete code examples. We mainly cover the following points.

  • Syntax of the fetch() method and a basic example
  • How to implement a GET request
  • How to handle response data

Basic syntax of the fetch() method

With the Fetch API, you send requests to a server using the fetch() method. Below is the basic syntax.

fetch(url, options)
  .then(response => {
    // Handle the response
  })
  .catch(error => {
    // Handle errors
  });

Arguments

  • url: The URL to which the request is sent.
  • options (optional): Option settings that include method, headers, body, and more.

Return value

  • Promise object: Returns the result of the asynchronous process.

How to implement a GET request

The most basic use of the Fetch API is a GET request, which retrieves data from a server.

Example: Fetch JSON data

fetch('https://jsonplaceholder.typicode.com/posts/1')
  .then(response => {
    if (!response.ok) {
      throw new Error('Network error');
    }
    return response.json(); // Retrieve data as JSON
  })
  .then(data => {
    console.log(data); // Display the retrieved data
  })
  .catch(error => {
    console.error('Error:', error); // Print an error log
  });

How to process response data

With the Fetch API, you can process response data in various formats. Below are common examples.

  1. Retrieve text data
fetch('https://example.com/data.txt')
  .then(response => response.text()) // Retrieve data as text
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));
  1. Retrieve binary data
fetch('https://example.com/image.jpg')
  .then(response => response.blob()) // Retrieve as binary data
  .then(blob => {
    const imgURL = URL.createObjectURL(blob);
    document.querySelector('img').src = imgURL;
  })
  .catch(error => console.error('Error:', error));
  1. Retrieve header information
fetch('https://example.com/api')
  .then(response => {
    console.log(response.headers.get('Content-Type')); // Get a header value
  })
  .catch(error => console.error('Error:', error));

Summary

Here, we covered a basic GET request using the Fetch API and how to handle responses.

The Fetch API is a flexible tool that makes it easy to retrieve many types of data, such as text, JSON, and binary data. Once you understand these fundamentals, it will be easier to apply them to the next chapter, including error handling and POST requests.

In the next section, we’ll explain error handling with the Fetch API in detail.

4. Error handling

In this section, we explain error handling when using the Fetch API. When communicating with a server, various issues can occur, such as network errors and response errors. Handling these properly can improve the user experience.

Basics of error handling

With the Fetch API, you can use the catch() method to handle cases such as network failures or error responses.

Basic error handling example

fetch('https://example.com/data')
  .then(response => {
    if (!response.ok) { // Check the response status code
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    return response.json();
  })
  .then(data => console.log(data))
  .catch(error => console.error('An error occurred:', error)); // Error handling

Error handling with try…catch

Using Async/Await lets you write cleaner, more readable code. In that case, you handle errors with a try...catch statement.

Example: Error handling with Async/Await

async function fetchData() {
  try {
    const response = await fetch('https://example.com/data');
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error('An error occurred:', error);
  }
}

fetchData();

Implementing timeouts

The Fetch API does not include a built-in timeout feature by default. However, implementing timeouts lets you handle slow responses appropriately.

Example: Implementing a timeout

function fetchWithTimeout(url, timeout = 5000) {
  return Promise.race([
    fetch(url),
    new Promise((_, reject) =>
      setTimeout(() => reject(new Error('Request timed out')), timeout)
    ),
  ]);
}

fetchWithTimeout('https://example.com/data', 5000)
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    return response.json();
  })
  .then(data => console.log(data))
  .catch(error => console.error('An error occurred:', error));

Detecting network errors

A network error refers to cases where the server cannot be reached or the connection is interrupted. With the Fetch API, these errors can also be detected with catch().

Example: Handling a network error

fetch('https://invalid-url.com/data')
  .then(response => response.json())
  .catch(error => console.error('Network error:', error.message));

Summary

In this section, we introduced error handling with the Fetch API, from basics to more advanced patterns.

Key takeaways

  • Check response status codes and implement error handling
  • Simplify error handling with Async/Await
  • Handle slow responses by implementing timeouts

Error handling is critical for improving the user experience. In the next section, we’ll explain POST requests for sending data to a server.

5. Sending POST requests

In this section, we explain how to send POST requests with the Fetch API to send data to a server. We’ll cover practical examples such as sending form data and JSON.

Basic syntax for POST requests

You can implement a POST request in the Fetch API by providing an options object as the second argument to the fetch() method.

Basic syntax

fetch(url, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(data),
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

Example: Sending JSON data

Below is an example of sending user information in JSON format.

const userData = {
  name: 'Taro Yamada',
  email: 'yamada@example.com',
};

fetch('https://example.com/api/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(userData),
})
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    return response.json();
  })
  .then(data => console.log('Success:', data))
  .catch(error => console.error('Error:', error));

Example: Sending form data

To send form data, use the FormData object.

const formData = new FormData();
formData.append('username', 'yamada');
formData.append('file', fileInput.files[0]);

fetch('https://example.com/upload', {
  method: 'POST',
  body: formData,
})
  .then(response => response.json())
  .then(data => console.log('Upload success:', data))
  .catch(error => console.error('Error:', error));

Example: Requests with authentication information

When sending data along with authentication information (for example, a token), add the auth data to the request headers.

fetch('https://example.com/api/protected', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
  },
  body: JSON.stringify({ message: 'Hello!' }),
})
  .then(response => response.json())
  .then(data => console.log('Success:', data))
  .catch(error => console.error('Error:', error));

Error handling for POST requests

For POST requests, you can add error handling like the following to deal with network issues or server-side problems.

async function postData(url, data) {
  try {
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(data),
    });

    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }

    const result = await response.json();
    console.log('Success:', result);
  } catch (error) {
    console.error('An error occurred:', error.message);
  }
}

postData('https://example.com/api/messages', { text: 'Hello!' });

Summary

In this section, we explained the basics and practical usage of POST requests using the Fetch API.

Key takeaways

  1. How to send JSON data and form data
  2. How to implement requests with authentication information
  3. How to strengthen error handling

POST requests are essential for two-way communication with servers. In the next section, we’ll explain customization options for the Fetch API in detail.

6. Other option settings

In this section, we explain various option settings you can specify as the second argument to the Fetch API. By using these, you can easily customize requests and manage authentication information.

Basic option syntax

Fetch API options are specified as an object in the second argument.

fetch(url, {
  method: 'GET',              
  headers: {                  
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
  },
  body: JSON.stringify(data), 
  credentials: 'include',     
  mode: 'cors',               
  cache: 'no-cache',          
  redirect: 'follow',         
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

Details of each option

  1. method (HTTP method)
  • Specifies the HTTP method (for example: GET, POST, PUT, DELETE).
  • The default is GET.
  1. headers (headers)
  • Specifies request headers.
  • Used to define the data format or add authentication information.
headers: {
  'Content-Type': 'application/json',
  'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
}
  1. body (sending data)
  • Used to send data to the server with POST or PUT methods.
  1. credentials (managing credentials)
  • Controls whether credentials (cookies or HTTP authentication data) are sent.
ValueDescription
omitDo not send credentials (default)
same-originSend credentials only for same-origin requests
includeSend credentials even for cross-origin requests
  1. mode (CORS policy)
  • Controls cross-origin request behavior.
ValueDescription
corsAllow cross-origin requests (default)
no-corsAllow only simple requests (limited)
same-originAllow requests only to the same origin
  1. cache (cache control)
  • Controls how request caching is used.
ValueDescription
defaultUse the browser’s default cache settings
no-storeDo not use cache; always make a new request
reloadIgnore cache and make a new request
  1. redirect (redirect handling)
  • Specifies how redirects are handled.
ValueDescription
followAutomatically follow redirects (default)
errorTreat redirects as errors
manualHandle redirects manually (controllable in code)

Advanced customization example

Below is an example that combines multiple options.

fetch('https://example.com/api/resource', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
  },
  body: JSON.stringify({ message: 'Hello!' }),
  credentials: 'include',
  mode: 'cors',
  cache: 'no-cache',
  redirect: 'follow',
})
  .then(response => response.json())
  .then(data => console.log('Success:', data))
  .catch(error => console.error('Error:', error));

Summary

In this section, we explained various Fetch API option settings in detail.

Key takeaways

  1. How to customize headers and credentials
  2. Fine-grained settings such as CORS and cache control
  3. Advanced patterns for redirects and error handling

In the next section, we’ll introduce concrete examples of how to use the Fetch API in practice.

7. Practical examples of using the Fetch API

In this section, we explain how you can use the Fetch API in real projects with concrete examples. Through practical scenarios, you’ll build real-world Fetch API skills.

Displaying a list of API data

A common use case in web applications is fetching data from an external API and displaying it as a list. In the example below, we fetch post data from the JSONPlaceholder API and display it as an HTML list.

Code example

const url = 'https://jsonplaceholder.typicode.com/posts';

fetch(url)
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    return response.json();
  })
  .then(posts => {
    const list = document.getElementById('post-list');
    posts.forEach(post => {
      const listItem = document.createElement('li');
      listItem.textContent = `${post.id}: ${post.title}`;
      list.appendChild(listItem);
    });
  })
  .catch(error => console.error('Error:', error));

HTML example

<ul id="post-list"></ul>

Submitting a form and registering data

This is an example of registering data from a form input to a server.

Code example

const form = document.getElementById('user-form');
form.addEventListener('submit', async (e) => {
  e.preventDefault();

  const formData = {
    name: document.getElementById('name').value,
    email: document.getElementById('email').value,
  };

  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/users', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(formData),
    });

    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }

    const result = await response.json();
    console.log('Registration successful:', result);
    alert('The user has been registered!');
  } catch (error) {
    console.error('Error:', error);
    alert('An error occurred.');
  }
});

HTML example

<form id="user-form">
  <input type="text" id="name" placeholder="Name" required />
  <input type="email" id="email" placeholder="Email address" required />
  <button type="submit">Register</button>
</form>

File upload

The Fetch API can also handle file uploads. Below is an example of uploading an image file to a server.

Code example

const fileInput = document.getElementById('file-input');
const uploadButton = document.getElementById('upload-button');

uploadButton.addEventListener('click', async () => {
  const file = fileInput.files[0];
  const formData = new FormData();
  formData.append('file', file);

  try {
    const response = await fetch('https://example.com/upload', {
      method: 'POST',
      body: formData,
    });

    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }

    const result = await response.json();
    console.log('Upload successful:', result);
    alert('The file has been uploaded!');
  } catch (error) {
    console.error('Error:', error);
    alert('Upload failed.');
  }
});

HTML example

<input type="file" id="file-input" />
<button id="upload-button">Upload</button>

Summary

In this section, we introduced practical examples using the Fetch API.

Key takeaways

  1. Creating a dynamic list by displaying API data
  2. Implementing form submission and data registration
  3. Implementing file uploads and search functionality

By using these examples as references, you can build interactive web applications powered by the Fetch API. In the next section, we’ll summarize the entire article and introduce learning resources for your next steps.

8. Summary

In this article, we explained JavaScript’s Fetch API systematically—from the basics to practical use. The Fetch API is a powerful tool that enables asynchronous communication concisely and efficiently, making it essential for modern web application development.

Review of what you learned

  1. Overview and features of the Fetch API
  • The Fetch API is Promise-based, allowing concise and flexible code.
  • Compared to traditional XMLHttpRequest, the syntax is simpler and easier to maintain.
  1. Basic usage and error handling
  • Basic syntax for fetching data with GET requests.
  • By adding error handling and timeout processing, you can implement more robust code.
  1. Sending data with POST requests
  • Examples of sending JSON data and form data.
  • Learned how to add authentication information and custom headers.
  1. Using option settings effectively
  • Introduced flexible customization methods such as cache control, CORS settings, and credential management.
  1. Practical examples
  • Learned real usage through examples like list display, form submission, file uploads, and search functionality.

Advantages and points to note for the Fetch API

Advantages

  • Code is concise and highly readable.
  • Works well with Promises and Async/Await, making it easy to combine with modern JavaScript syntax.
  • Supports many data formats such as JSON, binary data, and streams.

Points to note

  • There is no timeout feature by default, so you may need to implement it yourself.
  • It is not supported in older browsers (for example, Internet Explorer), so consider polyfills or alternatives if needed.

Learning resources for next steps

To deepen your understanding of the Fetch API, use the official documentation and resources below.

Finally

The Fetch API is a powerful tool that lets you implement server communication simply using modern JavaScript techniques. By applying what you learned in this article, you can build more interactive and feature-rich web applications.

As web development continues to evolve, API integration and asynchronous processing will become even more important. Master the Fetch API and sharpen your practical skills!

Next steps

  • Try creating a project that uses a real API.
  • Use custom options to implement more advanced request handling.
  • Challenge yourself to build full-stack applications that integrate with a server-side backend.

This concludes the article. We hope learning the Fetch API helps you improve your skills even further!

広告