Tools · Web testing tools · 21 / 23
Request and response panes: headers, body, and preview
Selecting a Network row opens the request headers, the request body, the response headers, and the response body. Preview renders JSON. Response shows the bytes. On Harbor Ledger you use that split to check the owner field and to see a POST that never got a response.
Headers first, on a row that completed
Select GET /api/invoices/1042. The Headers pane shows the request URL, the method, the status, the request headers, and the response headers. Read Accept and Content-Type as a pair. This call should ask for JSON and receive JSON. Read Set-Cookie far enough to see the name session and the flags HttpOnly and SameSite, and stop before the value becomes something you paste.
Cache-Control: no-store on this response is why a reload shows you a fresh invoice instead of a sticky one. If a bug is “I changed the status and the page shows the old one,” this header is the first thing to check, along with a disk-cache badge on the row. A cached 200 is a different bug from a fresh 200 of stale data.
Preview finds the field, raw quotes it
Open Preview. The invoice is a tree: id, title, owner, status, error. Owner should be avery@ledger.lab when you signed in as Avery. The error field is null. That null is data. It is the same trap as the ZAP rule that sees the word error and files a claim. In DevTools you can see the null and move on.
Open the Response pane and find the same owner string in the raw JSON. If you are writing a bug note, copy from here. Preview is allowed to present a friendlier tree. The response pane is the body. For a completed POST, do the same split: Payload shows what you sent, Preview and Response show what the app returned.
GET /api/invoices/1042
Status: 200
Response Content-Type: application/json
{"id":"1042","title":"April retainer","owner":"avery@ledger.lab","status":"open","error":null}The canceled POST has a payload and no response
Select the canceled POST /api/notes from the Preserve log lesson. Headers show the URL and the word canceled. Payload shows the note text you typed. Response is empty. That emptiness is the observation. Write “response pane empty” rather than a guessed JSON error. If you need to know whether the app stored anything, look at the invoice list and the lab log, not at a body that is not there.
After you fix the handler, the same panes should grow a real response: a status, a content type, and a body that names the note. The difference between the two captures is the bug, described without any tool but the browser.
Worked case: a wrong content type, caught in the panes
If you can edit the lab, temporarily point the invoice fetch at /invoices/1042, the HTML page, instead of /api/invoices/1042. Reload with the Network panel open. The row comes back 200, which looks healthy in the list, and the screen breaks or goes blank because the script parsed HTML as JSON. The Headers pane shows Content-Type: text/html. The Response pane shows the document. Put the fetch back, reload, and confirm Content-Type is application/json again.
That detour is a front-end bug you caused on purpose, on an app you own, to see a 200 lie. The status column was not enough. The panes were enough. You do not need a scanner to tell you the script and the body disagreed.
Diagram
Four panes, one exchange
- Headers
Request headers show Cookie and Accept. Response headers show status, Content-Type, and Set-Cookie.
- Payload
The request body, when there is one, is the note text or the form fields.
- Preview
JSON is shown as a tree so owner and status are easy to find.
- Response
The raw body is what you quote. A canceled POST has no response pane to quote.
The invoice fetch, as the panes split it
network · headers · GET /api/invoices/1042
Request URL: http://127.0.0.1:3000/api/invoices/1042 Method: GET Status: 200 Request headers Accept: application/json Cookie: session=lab-session-avery
Response headers Content-Type: application/json Cache-Control: no-store Set-Cookie: session=lab-session-avery; HttpOnly; SameSite=Lax
- The URL and the method are the identity of the row.
- Cookie is present. You do not copy the value into the bug note.
- Content-Type says the preview should be JSON.
network · preview · invoice JSON
No request body on this GET.
{
"id": "1042",
"title": "April retainer",
"owner": "avery@ledger.lab",
"status": "open",
"error": null
}- Preview is a tree of the same JSON the raw pane shows.
- Owner matches Avery. Error is null, which is data, not a failure.
- Quote from the raw response if a character is in dispute.
URL: http://127.0.0.1:3000/api/invoices/1042 Method: GET Status: 200 Request Content-Type: (none, no body) Response Content-Type: application/json Checked in preview: owner, status, error Quoted from raw: owner = avery@ledger.lab Cookie: not copied
Check yourself
1. The invoice screen is blank. The fetch row is status 200, Accept is application/json, and the response Content-Type is text/html. Where do you look next?
2. Preview shows owner avery@ledger.lab. Why glance at the raw response before you file the note?
3. The canceled POST shows a request payload and an empty response pane. What is a true statement?