ajax_fetch_request
Making Requests with the Fetch API
Section titled “Making Requests with the Fetch API”The fetch() API is the modern, promise-based standard for making asynchronous HTTP requests in the browser (and other environments like Node.js). It replaces the older XMLHttpRequest object with a cleaner and more powerful interface.
Basic Fetch Request (GET)
Section titled “Basic Fetch Request (GET)”The simplest use of fetch() takes one argument: the URL of the resource you want to fetch. By default, it makes a GET request.
fetch() returns a Promise that resolves to the Response to that request, whether it is successful or not. You’ll learn how to handle the response in the next chapter.
// Basic GET requestfetch('https://api.example.com/users') // URL of the API endpoint or resource .then(response => { // First step: check if the request was successful (status code 200-299) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } // Second step: parse the response body (e.g., as JSON) return response.json(); // returns another promise }) .then(data => { // Third step: use the parsed data console.log('Data received:', data); }) .catch(error => { // Handle network errors or errors thrown in the .then() blocks console.error('Fetch error:', error); });
// Using async/await (often preferred for readability)async function fetchData(url) { try { const response = await fetch(url); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); console.log('Data received (async/await):', data); } catch (error) { console.error('Fetch error (async/await):', error); }}
fetchData('https://api.example.com/users');Note: fetch() only rejects its promise on network failure (e.g., DNS error, no connection). HTTP error statuses like 404 (Not Found) or 500 (Server Error) do not cause the promise to reject. You must check response.ok or response.status manually.
Configuring the Request with Options
Section titled “Configuring the Request with Options”fetch() can accept an optional second argument, an init object, to customize the request (method, headers, body, etc.).
| Option | Description |
|---|---|
method | The HTTP request method, e.g., ‘GET’ (default), ‘POST’, ‘PUT’, ‘DELETE’, ‘PATCH’, ‘HEAD’. |
headers | An object or Headers object containing request headers, e.g., { 'Content-Type': 'application/json', 'Accept': 'application/json' }. |
body | The request body. Can be a string, Blob, BufferSource, FormData, URLSearchParams, or ReadableStream. Must match the Content-Type header. Often used with POST, PUT, PATCH. |
mode | Controls handling of cross-origin requests, e.g., ‘cors’ (default), ‘no-cors’, ‘same-origin’. |
cache | Controls how the request interacts with the browser’s HTTP cache, e.g., ‘default’, ‘no-store’, ‘reload’. |
credentials | Controls whether cookies are sent with the request, e.g., ‘include’, ‘same-origin’ (default), ‘omit’. |
GET vs. POST
Section titled “GET vs. POST”GET: Used to request data from a specified resource. Data is often sent via URL query parameters. Should not change server state (idempotent). Requests can be cached and bookmarked.
POST: Used to submit data to be processed to a specified resource (e.g., create a new item, submit a form). Data is sent in the request body. Can change server state. Requests are not typically cached or bookmarked.
GET Request with Query Parameters
Section titled “GET Request with Query Parameters”For GET requests, data is usually appended to the URL.
// Manually constructing the URLconst userId = 123;fetch(`/api/users/${userId}?include=profile&theme=dark`);
// Using URLSearchParams for safer encodingconst params = new URLSearchParams({ include: 'profile', theme: 'dark'});fetch(`/api/users/${userId}?${params.toString()}`);POST Request with JSON Body
Section titled “POST Request with JSON Body”To send JSON data using POST:
- Set
methodto'POST'. - Set the
Content-Typeheader to'application/json'. - Provide the JSON data (as a string) in the
bodyoption usingJSON.stringify().
async function createUser(userData) { try { const response = await fetch('/api/users', { method: 'POST', // Specify the method headers: { 'Content-Type': 'application/json' // Indicate we're sending JSON }, body: JSON.stringify(userData) // Convert the JS object to a JSON string });
if (!response.ok) { // Handle potential errors (e.g., validation errors from the server) const errorData = await response.json().catch(() => ({ message: 'Unknown error' })); // Try to parse error details throw new Error(`Failed to create user: ${response.status} - ${errorData.message}`); }
const createdUser = await response.json(); // Get the newly created user data console.log('User created:', createdUser); return createdUser;
} catch (error) { console.error('Error creating user:', error); }}
const newUser = { name: 'Jane Doe', email: 'jane.doe@example.com' };createUser(newUser);Cross-Origin Resource Sharing (CORS)
Section titled “Cross-Origin Resource Sharing (CORS)”For security reasons, browsers restrict web pages from making requests to a different domain (origin) than the one that served the page. If your frontend code (e.g., at mysite.com) tries to fetch data from an API at a different domain (e.g., api.externalservice.com), the browser will block the request unless the server at api.externalservice.com includes specific CORS headers (like Access-Control-Allow-Origin) in its response.
If you encounter CORS errors in the browser console, it usually means the server needs to be configured to allow requests from your frontend’s origin. This is not something you typically fix purely on the client-side (unless using modes like ‘no-cors’ which has limitations).
Learn more about fetch() on MDN: https://developer.mozilla.org/en-US/docs/Web/API/fetch