JS AJAX Response
In this page:
Reading a JSON Response
response.json() parses the response body as JSON and returns a Promise resolving to the parsed JavaScript value -- the most common way to read structured API responses, since most modern APIs return JSON by default.
Note: Always await or .then() the result of response.json(), since parsing the body is itself an asynchronous operation, not an instant synchronous one.
Warning: Calling response.json() on a response whose body is not actually valid JSON (like an HTML error page from the server) throws an error rather than returning something usable.
Example: Reading a JSON Response
fetch("data.php")
.then(response => response.json())
.then(data => console.log(data));
Checking response.ok and Status
response.ok is a boolean, true only when the HTTP status is in the 200-299 range -- checking it (or response.status directly) is essential, since fetch's promise resolves normally even for a 404 or 500 response, unlike what you might expect from a "failed" request.
Note: Check response.ok immediately after the fetch resolves, before attempting to parse the body, so a failed request is caught early rather than producing a confusing parse error later.
Warning: Assuming a resolved fetch promise always means success is one of the most common fetch-related bugs -- an HTTP error status still resolves the promise successfully.
Example: Checking response.ok and Status
fetch("data.php").then(response => {
console.log(response.ok, response.status); // check before trusting the data
return response.json();
});
Reading Text and Other Response Formats
response.text() reads the body as a plain string, useful for HTML fragments or plain-text responses, while response.blob() reads binary data (like an image or file), each returning a Promise, exactly like response.json().
Note: Match the response-reading method to the actual content the server sends -- .text() for plain text or HTML, .json() for JSON, .blob() for binary files.
Warning: Calling the wrong parsing method for the actual response format (like .json() on a plain-text response) produces unhelpful errors or garbled data.
Example: Reading Text and Other Response Formats
fetch("data.php").then(response => response.text()).then(text => console.log(text));
Reading Response Headers
response.headers.get(headerName) reads a specific header from the response, useful for metadata a server sends alongside the body -- like Content-Type to confirm the format, or custom pagination headers indicating how many total results exist.
Note: Use response.headers.get() to read metadata the server intentionally provides outside the body, rather than trying to encode everything into the response body itself.
Warning: Header names are case-insensitive when reading with .get(), but this is easy to forget when debugging a header that seems to be missing.
Example: Reading Response Headers
fetch("data.php").then(response => {
console.log(response.headers.get("Content-Type"));
});
The Response Body Can Only Be Read Once
A response's body is a stream that can only be consumed a single time -- calling response.json() and then response.text() on the same response object fails on the second call, since the body has already been read and drained.
Note: If you genuinely need to read a response body more than once (rare), clone it first with response.clone() before consuming the original.
Warning: Attempting to read an already-consumed response body throws an error ("body stream already read"), a confusing message if you do not know about this one-time-use constraint.
Example: The Response Body Can Only Be Read Once
fetch("data.php").then(response => {
return response.json().then(data => {
console.log(data);
// return response.text(); // would fail, body already read
});
});
- Calling response.json() on a response that is not actually JSON (like an HTML error page), which throws a parsing error rather than returning the unexpected content.
- Forgetting that fetch()'s promise only rejects on a network failure, not on an HTTP error status -- response.ok must be checked explicitly to detect a 404 or 500.
- Trying to read a fetch response body more than once -- the body stream can only be consumed a single time per response object.
- response.json(), response.text(), and response.blob() each parse the response body in a different format, and each returns a Promise.
- response.ok is true only for HTTP status codes 200-299 -- always check it before treating a response as successful.
- response.headers.get(name) reads a specific response header, useful for content type or pagination metadata.
Reading fetch and XMLHttpRequest responses works identically in every modern browser.
Chapter Quiz — Complete all 26 topics to unlock
0/26 topics done
Complete these topics first:
- JS JSON
- JS Regular Expressions
- JS Fetch API
- JS LocalStorage and SessionStorage
- JS Cookies
- JS setTimeout and setInterval
- JS Event Loop
- JS Web Workers
- JS Service Workers
- JS AJAX
- JS AJAX Intro
- JS AJAX XMLHttp
- JS AJAX Request
- JS AJAX Response
- JS AJAX XML
- JS AJAX PHP
- JS AJAX Database
- JS JSONP
- JS RegExp Flags
- JS RegExp Classes
- JS RegExp Metachars
- JS RegExp Assertions
- JS RegExp Groups
- JS RegExp Quantifiers
- JS JSON HTML
- JS JSON vs XML