← Back to JavaScript Course | Chapter 9: Async & Web APIs | Lesson 13 of 26

JS AJAX Request

Beyond a simple GET, an AJAX request often needs to carry data to the server -- query parameters for filtering, a JSON body for creating a record, custom headers for authentication -- and configuring these correctly on the request is essential for it to be understood and processed properly by the server.
Syntax
javascript
xhr.open("GET", url, true);
xhr.send();

xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(data);

Passing Data via Query Parameters

For a GET request, data is typically passed as query parameters appended to the URL after a ? -- like /search?term=widgets&limit=10 -- which the server reads and parses from the incoming request's URL.

Note: Use URLSearchParams to build a query string safely rather than manually concatenating strings with & and =, which is easy to get wrong.
Warning: A raw, un-encoded value containing an & or = character inserted directly into a query string will corrupt the URL's structure.

उदाहरण: Passing Data via Query Parameters

javascript
// Declare the constant `term`, set to "widgets"
// Declare the constant `term`, set to "widgets"
const term = "widgets";
// Declare the constant `limit`, set to `10`
// Declare the constant `limit`, set to `10`
const limit = 10;
// Define the method `fetch` taking ``search.php?term`
fetch(`search.php?term=${term}&limit=${limit}`)
  // On success, run this with the resolved value as `r`
  .then(r => r.json())
  // On success, run this with the resolved value as `data`
  .then(data => console.log(data));

Sending a JSON Request Body

For POST, PUT, or PATCH requests, data is usually sent in the request body as JSON -- JSON.stringify() converts a JavaScript object into that JSON string, and the Content-Type: application/json header tells the server how to correctly parse the body it receives.

Note: Always pair JSON.stringify() in the body with a Content-Type: application/json header -- sending JSON without that header can cause some servers to misinterpret the body.
Warning: Forgetting to call JSON.stringify() and sending a raw JavaScript object directly as the body sends the unhelpful text "[object Object]" instead of actual JSON data.

उदाहरण: Sending a JSON Request Body

javascript
// Send a POST request with a JSON body to save.php
fetch("save.php", {
  method: "POST",
  headers: { "Content-Type": "application/json" }, // tell the server we're sending JSON
  body: JSON.stringify({ name: "Sam" }), // convert the JS object into a JSON string
}).then(r => r.json()).then(data => console.log(data)); // parse and log the server's JSON reply

Sending Form Data

FormData is a built-in object that represents form-style data, including file uploads -- constructing one from an actual <form> element (or manually appending fields) and passing it directly as a fetch body sends it with the correct multipart/form-data encoding automatically, no manual Content-Type header needed.

Note: Let the browser set the Content-Type header automatically when sending FormData -- setting it manually can actually break the request by omitting the required boundary parameter.
Warning: FormData is required (rather than JSON) whenever a request needs to include an actual file upload, since JSON cannot represent binary file data.

उदाहरण: Sending Form Data

javascript
// Declare the constant `formData` as a new `FormData` instance
// Declare the constant `formData` as a new `FormData` instance
const formData = new FormData();
// Call `formData.append("name", "Sam")`
// Call `formData.append("name", "Sam")`
formData.append("name", "Sam");
// Define the method `fetch` taking `"upload.php"`, `{ method: "POST", body: formData }`
// Define the method `fetch` taking `"upload.php"`, `{ method: "POST", body: formData }`
fetch("upload.php", { method: "POST", body: formData })
  // On success, run this with the resolved value as `r`
  // On success, run this with the resolved value as `r`
  .then(r => r.json())
  // On success, run this with the resolved value as `data`
  // On success, run this with the resolved value as `data`
  .then(data => console.log(data));

Setting Custom Request Headers

The headers option (in fetch) or .setRequestHeader() (in XMLHttpRequest) attaches additional metadata to a request -- most commonly an Authorization header carrying an API token, letting the server verify the request came from an authenticated user.

Note: Store sensitive tokens (like an API key) outside your client-side JavaScript source when possible, since anything shipped to the browser is visible to anyone inspecting the page.
Warning: Certain headers (like Origin or Host) are protected and cannot be set manually by JavaScript for security reasons, no matter how they are specified.

उदाहरण: Setting Custom Request Headers

javascript
// Send a GET request to data.php with a Bearer auth token
fetch("data.php", {
  headers: { "Authorization": "Bearer sample-token" }, // proves who is making the request
}).then(r => r.json()).then(data => console.log(data)); // parse and log the JSON reply

Choosing an HTTP Method

The method option specifies the HTTP verb for the request -- GET for reading data (the default), POST for creating something new, PUT or PATCH for updating, and DELETE for removing -- matching the method to the operation's actual meaning helps servers and any caching layers behave correctly.

Note: Match your request's method to its actual semantic purpose (GET for reads, POST for creates, and so on), rather than defaulting to GET or POST for everything.
Warning: Browsers and proxies may cache GET requests aggressively -- using GET for an operation that actually changes server state can produce confusing, inconsistent caching behavior.

उदाहरण: Choosing an HTTP Method

javascript
fetch("delete.php", { method: "DELETE" }).then(r => console.log(r.status));
fetch("update.php", { method: "PUT" }).then(r => console.log(r.status));
Live Example
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.