Skip to content

The headers you will actually meet

Content type, caching and CORS explain most of what looks mysterious in a network tab.

Lesson 3 of 4 · about 3 minutes

Content-Type is not a suggestion

Content-Type tells the other side how to read the body. Send JSON as text/plain and a strict client will refuse to parse it; send HTML as text/plain and a browser shows the markup instead of rendering it.

X-Content-Type-Options: nosniff tells the browser to believe the declared type rather than guessing from the content. Without it, a browser that guesses can be talked into treating an uploaded file as a script, which is a real attack and the reason that header is in every hardening guide.

Caching, in two numbers

Cache-Control: max-age=600 means "reuse this for ten minutes without asking". An ETag is a fingerprint of the response: send it back as If-None-Match and the server can answer 304 Not Modified with no body at all, which is the cheapest useful response there is.

The pair is how a site stays fast without going stale: a short max-age for freshness, an ETag so the revalidation costs almost nothing. immutable is for files whose name changes when the content does — a hashed asset can be cached for a year precisely because a new version is a different URL.

CORS is the browser’s rule, not the server’s

A browser will not let a page read a response from another origin unless that response says it may, with Access-Control-Allow-Origin. The request often still happens; what is blocked is your JavaScript reading the answer.

This is why a call works in curl and fails in the browser: curl has no origin and enforces nothing. It is also why CORS is not a server-side protection — it protects users from pages, not servers from clients. A server that needs to refuse a caller must check that itself.

A request with a JSON content type or a custom header triggers a preflight: an OPTIONS request asking whether the real one is allowed. A "mysterious" OPTIONS in the network tab is almost always this, and a missing allowed header in its response is why the real request never followed.

Worked examples

  • Revalidate instead of downloading again

    /If-None-Match: W/"ecfd1202e34d"/

    Against: Answered with 304 Not Modified and no body

    The ETag came from the earlier response. The saving is the whole body, every time nothing has changed.

Check yourself

Practice questions written for this lesson — not past exam papers.

Practise every question in this subject

  1. A request works in curl and fails in the browser with a CORS error. What does that tell you?

  2. What is an ETag for?