A conditional request is an ordinary request carrying a precondition. The server evaluates it and either fulfils the request normally or responds that nothing has changed.
The first request
The client asks for a resource and the server responds with the content plus validators:
HTTP/1.1 200 OK
ETag: "9f2c1a7b3e4d5f6a"
Last-Modified: Wed, 12 Feb 2025 09:14:22 GMT
Cache-Control: public, max-age=600, must-revalidate
The second request
Later, the client asks again, this time presenting the validator it holds:
GET /test-page/ HTTP/1.1
If-None-Match: "9f2c1a7b3e4d5f6a"
If the resource is unchanged, the server replies:
HTTP/1.1 304 Not Modified
ETag: "9f2c1a7b3e4d5f6a"
No body. The client reuses what it already has.
Testing it properly
Confirming a 304 arrives is only half the test. You also need to confirm the server is actually comparing rather than answering 304 unconditionally.
- Send the correct ETag — expect 304
- Send a deliberately wrong ETag — expect 200
- Send the correct
Last-Modified— expect 304 - Send a very old date — expect 200
A server that returns 304 for all four is broken in a way that would silently invalidate any measurement built on top of it.
A common failure
Plenty of sites emit an ETag and then ignore If-None-Match entirely, returning a full 200 with a fresh body every time. The header is present, so the site looks correctly configured, but no client ever benefits from it. Test rather than assume.