fetch gives you a Response object. Before reading the data, you can look at what the server said.
const response = new Response(JSON.stringify({ name: "Maya" }), {
status: 200,
headers: { "Content-Type": "application/json" }
});
console.log(response.ok); // → true
console.log(response.status); // → 200
console.log(response.statusText); // →
console.log(response.headers.get("Content-Type")); // → application/json
(new Response(...) creates a response by hand, which is useful to learn from. A real fetch gives you one with real values, including statusText.)
The important properties
| Property | Meaning |
|---|---|
response.ok | true if the status is 200 to 299 |
response.status | the number: 200, 404, 500… |
response.statusText | the short text, such as "Not Found" |
response.headers | the response headers |
response.url | the final URL (after redirects) |
response.redirected | whether it was redirected |
Status codes in short
| Range | Meaning | Examples |
|---|---|---|
| 2xx | success | 200 OK, 201 Created, 204 No Content |
| 3xx | redirect | 301, 302, 304 |
| 4xx | client error (your request) | 400 Bad Request, 401, 403, 404 Not Found, 429 Too Many Requests |
| 5xx | server error | 500, 502, 503 |
Reading the body
Choose one method. Each returns a promise.
async function demo() {
const make = () => new Response('{"id":7}', { headers: { "Content-Type": "application/json" } });
console.log(await make().json()); // → { id: 7 }
console.log(await make().text()); // → {"id":7}
}
demo();
| Method | Returns |
|---|---|
json() | parsed data |
text() | a string |
blob() | a file-like object (images, downloads) |
arrayBuffer() | raw bytes |
formData() | form data |
The body can be read only once
async function demo() {
const response = new Response("hello");
console.log(await response.text()); // → hello
try {
await response.text();
} catch (error) {
console.log(error.name); // → TypeError
}
console.log(response.bodyUsed); // → true
}
demo();
If you need to read it twice (for example to log it and use it), call response.clone() first.
Checking the content type
An API may return HTML (an error page) when you expected JSON. Checking the header avoids confusing parse errors.
function isJSON(response) {
return (response.headers.get("Content-Type") || "").includes("application/json");
}
console.log(isJSON(new Response("{}", { headers: { "Content-Type": "application/json" } }))); // → true
console.log(isJSON(new Response("<html>"))); // → false
No content
A 204 No Content response has no body, so response.json() would fail. Check the status before parsing.
Calling json() on an error page
response.json() throws “Unexpected token <“. Check response.ok first, see HTTP Errors.