AJAX Request
Making Requests with the Fetch API
Section titled “Making Requests with the Fetch API”The modern standard for making asynchronous HTTP requests in browsers is the Fetch API. It provides a more powerful and flexible interface than the older XMLHttpRequest.
Basic Fetch Request (GET)
Section titled “Basic Fetch Request (GET)”The simplest use of fetch() involves just providing the URL of the resource you want to retrieve. By default, this performs a GET request.
fetch('https://api.example.com/users') // URL of the resource .then(response => { // Check if the response was successful (status code 200-299) if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); } return response.json(); // Parse the response body as JSON }) .then(data => { console.log('Data received:', data); // Process the received data }) .catch(error => { console.error('Fetch error:', error); // Handle errors (network issues, parsing errors, etc.) });fetch() returns a Promise that resolves to the Response object representing the response to the request. You then use methods like .json() or .text() on the Response object to access the actual data, which also return Promises.
Configuring the Request with Options
Section titled “Configuring the Request with Options”To customize the request (e.g., use POST, send data, set headers), pass an options object as the second argument to fetch().
| Option | Description |
|---|---|
method | The HTTP request method (e.g., ‘GET’, ‘POST’, ‘PUT’, ‘DELETE’, ‘PATCH’). Defaults to ‘GET’. |
headers | An object or Headers instance containing request headers (e.g., {'Content-Type': 'application/json'}). |
body | The request body. Can be a string, Blob, BufferSource, FormData, URLSearchParams, or ReadableStream. Must match the Content-Type header. |
mode | Controls whether cross-origin requests are allowed (e.g., ‘cors’, ‘no-cors’, ‘same-origin’). Defaults to ‘cors’. |
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 cross-origin requests (‘include’, ‘same-origin’, ‘omit’). |
GET vs. POST
Section titled “GET vs. POST”Choosing between GET and POST depends on the action you want to perform:
- GET: Use for retrieving data. Requests can be cached, bookmarked, and remain in browser history. Data is sent in the URL.
- POST: Use for submitting data that creates or updates a resource. Requests are not cached by default, don’t remain in browser history, and have no restrictions on data length. Data is sent in the request body.
Always use POST when:
- The request modifies data on the server (creating, updating, deleting).
- Sending sensitive information (like passwords).
- Sending large amounts of data.
- Sending binary data.
GET Request with Query Parameters
Section titled “GET Request with Query Parameters”To send data with GET, append it to the URL as query parameters. You can use URLSearchParams to construct the query string safely.
const params = new URLSearchParams({ userId: '123', limit: 10});
fetch(`https://api.example.com/posts?${params}`) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error(error));Adding a random parameter (?_=${Date.now()}) is generally not the modern way to prevent caching. Use appropriate Cache-Control headers on the server response and the cache option in the fetch request if needed.
POST Request with JSON Data
Section titled “POST Request with JSON Data”To send JSON data using POST, stringify your JavaScript object and set the Content-Type header to application/json.
const userData = { name: 'John Doe', email: 'john.doe@example.com'};
fetch('https://api.example.com/users', { method: 'POST', headers: { 'Content-Type': 'application/json' // Add other headers like Authorization if needed // 'Authorization': 'Bearer YOUR_API_TOKEN' }, body: JSON.stringify(userData) // Convert JS object to JSON string}).then(response => { if (!response.ok) { // If server returns error status, parse potential JSON error message return response.json().then(errData => { throw new Error(errData.message || `HTTP error! Status: ${response.status}`); }); } // Check if response has content before parsing JSON const contentType = response.headers.get('content-type'); if (contentType && contentType.includes('application/json')) { return response.json(); // Successfully created, maybe returns new user object } else { return {}; // Or handle non-JSON success response (e.g., status 201/204) }}).then(data => { console.log('Success:', data); // Handle successful creation (e.g., display success message)}).catch(error => { console.error('Error posting data:', error); // Display error message to the user});POST Request with Form Data
Section titled “POST Request with Form Data”You can easily send data from an HTML form using the FormData object. Fetch automatically sets the correct Content-Type (multipart/form-data) when using FormData.
const myForm = document.getElementById('myFormElement');
myForm.addEventListener('submit', function(event) { event.preventDefault(); // Prevent default form submission
const formData = new FormData(myForm);
// You can append extra data if needed: // formData.append('extraField', 'extraValue');
fetch('/submit-form', { method: 'POST', body: formData // No 'Content-Type' header needed; browser sets it for FormData }) .then(response => response.json()) // Assuming server responds with JSON .then(data => console.log('Form submission successful:', data)) .catch(error => console.error('Form submission error:', error));});The URL - A Server Endpoint
Section titled “The URL - A Server Endpoint”The first argument to fetch is typically the URL of a server endpoint (API). This endpoint is designed to receive the request, process it (e.g., interact with a database, perform calculations), and send back a response.
This endpoint can be hosted on the same server as your web page or on a different server (requiring proper CORS configuration).
Asynchronous Nature
Section titled “Asynchronous Nature”Fetch is inherently asynchronous and Promise-based. This means:
- JavaScript execution does not wait for the request to complete.
- The browser remains responsive, allowing users to interact with the page.
- You handle the response when the Promise resolves (using
.then()orawait).
Synchronous requests (XMLHttpRequest with async=false) should not be used. They block the browser’s main thread, leading to a frozen user interface and a terrible user experience. Modern web development relies exclusively on asynchronous patterns.