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

JS AJAX Response

Once an AJAX request completes, the response needs to be read in the correct format -- plain text, JSON, or occasionally XML -- and the response's status and headers checked before trusting its contents, since a completed request is not automatically a successful one.

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

javascript
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

javascript
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

javascript
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

javascript
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

javascript
fetch("data.php").then(response => {
  return response.json().then(data => {
    console.log(data);
    // return response.text(); // would fail, body already read
  });
});
Common Mistakes
  1. 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.
  2. 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.
  3. Trying to read a fetch response body more than once -- the body stream can only be consumed a single time per response object.
Chapter Summary
  • 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.
Browser Support

Reading fetch and XMLHttpRequest responses works identically in every modern browser.

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.