Send Ajax GET and POST requests
jQuery $.ajax(), $.get(), $.post(), $.getJSON()
In short
Use fetch(). It returns a promise for a Response; read the body with response.json() or response.text(), which are asynchronous too12. Check response.ok first: a 404 does not reject the promise, only a network failure does12. fetch has been available across browsers since March 20171.
The answer: GET
async function getJSON(url) {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Response status: ${response.status}`);
}
return response.json();
}
const item = await getJSON("https://example.test/api/items/1");
console.log(item.title); // "hello"fetch() starts the request and resolves to a Response as soon as the headers are in1. The body is read by a second asynchronous call: json(), text(), blob(), formData() or arrayBuffer(), and json() throws if the body is not valid JSON2. The ok property is true for a status from 200 to 2993.
The answer: POST
async function postJSON(url, payload) {
const response = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
});
if (!response.ok) {
throw new Error(`Response status: ${response.status}`);
}
return response.json();
}
const saved = await postJSON("https://example.test/api/items", { p1: 1, p2: "Hello World" });
console.log(saved.received.p2); // "Hello World"The Content-Type header tells the server the format of the body; set headers through the headers option as a plain object2. To send a form the way a browser would, pass a FormData object as the body and set no Content-Type at all; the browser writes the multipart header itself. FormData, URLSearchParams, a string, a Blob and a File are all accepted body types2.
<form id="signup"><input name="email" value="[email protected]"></form>const form = document.querySelector("#signup");
const response = await fetch("https://example.test/api/signup", {
method: "POST",
body: new FormData(form),
});
console.log(response.status); // 200In jQuery
$.getJSON("https://example.test/api/items/1", function (item) {
console.log(item.title);
});
$.post("https://example.test/api/items", { p1: 1, p2: "Hello World" }, function (saved) {
console.log(saved.method);
});jQuery’s $.ajax() and its shorthands guess the response type from the MIME type unless dataType says otherwise, always add the header X-Requested-With: XMLHttpRequest, and return a jqXHR object that has implemented the Promise interface since jQuery 1.55.
Browser support
fetch()is Baseline widely available: across browsers since March 20171.AbortSignal.timeout(), used below, is widely available since April 20244. The 2015 version of this page usedXMLHttpRequestwith anActiveXObjectfallback for Internet Explorer 6; none of that is needed.
Differs from jQuery A 404 or a 500 does not reject the
fetch()promise; only a badly formed URL or a network error does, so theokcheck is not optional12. Nothing is parsed for you: jQuery guesses JSON from the MIME type5,fetchhands you a body you read once withjson()2. NoX-Requested-Withheader is sent; jQuery always adds one5, and a server that detects Ajax by it needs the header set inheaders. A body can be read only once; callresponse.clone()before the first read if you need it twice2.
Timeouts and cancelling
try {
const response = await fetch("https://example.test/api/slow", { signal: AbortSignal.timeout(500) });
console.log(response.status);
} catch (err) {
if (err.name === "TimeoutError") console.log("gave up after 500 ms");
else throw err;
}AbortSignal.timeout(ms) returns a signal that aborts on its own after the given time, with a TimeoutError4. For a cancel button, create an AbortController, pass its signal, and call controller.abort(); the promise then rejects with an AbortError2.
const controller = new AbortController();
const request = fetch("https://example.test/api/items", { signal: controller.signal });
controller.abort();
try {
await request;
} catch (err) {
console.log(err.name); // "AbortError"
}Security Never build a URL or a body from user input without encoding it: put query values through
URLSearchParamsand send JSON throughJSON.stringify(), as above. Credentials for another origin are not sent unless you ask, and that is the right default.
Sources
- Window: fetch() method, MDN (accessed 2026-10-29)
- Using the Fetch API, MDN (accessed 2026-10-29)
- Response: ok property, MDN (accessed 2026-10-29)
- AbortSignal: timeout() static method, MDN (accessed 2026-10-29)
- jQuery.ajax(), jQuery API documentation (accessed 2026-10-29)
Last reviewed 2026-10-30. Tested in Chromium 148, 2026-10-29 by the snippet harness.