Request
Represents method, URL, headers and body for an outgoing request.
Request, Response and Headers are the structured objects behind fetch. They model HTTP messages in JavaScript.
const request = new Request("/api/records", { headers: { Accept: "application/json" } }); console.log(request.headers.get("Accept"));
JSON & Structured Data
Request represents an outgoing HTTP request. Response represents an incoming HTTP response. Headers stores HTTP header names and values.
You can pass a URL and options to fetch, or you can create a Request object first. Response objects can also be created manually for tests and demos.
Always check response.ok before trusting response data. HTTP errors such as 404 or 500 do not automatically reject the fetch promise.
Represents method, URL, headers and body for an outgoing request.
Represents status, headers and body returned by a request.
Case-insensitive header collection.
True for successful 2xx status codes.
Examples
const response = await fetch("/api/records"); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } const data = await response.json();
const response = await fetch("/api/records"); const data = await response.json(); // A 500 response can still reach this line.
Syntax reference
This is the practical reference part of the lesson. Each example has one job, a stable anchor and a small assignment, so the page works both as a course and as a developer reference when you need the syntax later.
Prepare a request object.
const request = new Request("/api/records", { method: "GET", headers: { Accept: "application/json" } });
Headers names are case-insensitive.
const headers = new Headers({ "Content-Type": "application/json" }); console.log(headers.get("content-type"));
Do not parse failed HTTP responses blindly.
const response = await fetch(request); if (!response.ok) { throw new Error(`HTTP ${response.status}`); }
Useful for tests and examples.
const response = new Response(JSON.stringify({ ok: true }), { headers: { "Content-Type": "application/json" } });
Code patterns
These patterns focus on the data boundaries you will use constantly: JSON, URLs, forms, files, fetch objects and binary buffers.
Prepare a request object.
const request = new Request("/api/records", { method: "GET", headers: { Accept: "application/json" } });
Headers names are case-insensitive.
const headers = new Headers({ "Content-Type": "application/json" }); console.log(headers.get("content-type"));
Do not parse failed HTTP responses blindly.
const response = await fetch(request); if (!response.ok) { throw new Error(`HTTP ${response.status}`); }
Useful for tests and examples.
const response = new Response(JSON.stringify({ ok: true }), { headers: { "Content-Type": "application/json" } });
Rules that matter
Structured data becomes reliable when every boundary is explicit: text to object, form to values, URL to parameters, response to JSON and bytes to meaning.
Fetch only rejects for network-level failures by default.
It normalizes access and casing.
Tell the server what response type you expect.
JSON request bodies should say they are JSON.
Response body streams can usually be consumed only once.
HTTP success and valid JSON are different concerns.
Production thinking
Request and Response make HTTP behavior explicit, which is essential for reliable API code.
API errors should become clear user-facing status messages instead of silent failures.
Production fetch wrappers should handle timeout, abort, status codes and parse errors consistently.
Client-side data fetching should not hide critical crawlable content when SEO matters.
Live code lab
The preview runs inside an isolated iframe. The JavaScript is placed inside the HTML editor for now, so every example stays together and remains easy to understand.
Mini assignment
Practice assignment
Try it yourself
Self-check
Structured data is safe only when you know where it came from, what shape it has and what conversion happened before use.