HTTPQUERY
中文

304 Not Modified

Usage

The 304 Not Modified status code is sent when the request is safe, such as a GET or HEAD request, and the server determines the resource has not changed since the version stored in the client’s cache. This conserves bandwidth because the server does not retransmit data the client already holds.

The server generates one or more of the following headers in response:

Because the goal of the 304 Not Modified response is to minimize bandwidth, the server omits headers not included in the original request unless they aid the cache-update process.

For conditional GET requests, the relevant directives are If-None-Match and If-Modified-Since. These rely on a validator such as ETag to evaluate whether the resource needs retransmission.

Example

The client requests a resource, receives an ETag identifying the version, then later revalidates. The server recognizes the resource is unchanged and returns 304 Not Modified. On the third request, a new version is available and a full 200 response is sent with an updated ETag.

Stale 304 trap

A 304 confirms the cached version is still current. When the server previously served a broken page (empty body, error content) with a 200 and the crawler cached the result, a subsequent 304 tells the crawler the broken version persists. The crawler stops rechecking because the “content” has not changed. Fixing the page alone is not enough. The server must return a fresh 200 with the corrected body (and a new ETag) to replace the cached error. Debugging this scenario is difficult because the root cause (a past transient error) is no longer visible.

Initial request

GET /news.html HTTP/1.1
Host: example.com

Initial response

HTTP/1.1 200 OK
ETag: "1234000"
Content-Type: text/html
Content-Length: 1250

<message body contains requested resource>

Second request

GET /news.html HTTP/1.1
Host: example.com
If-None-Match: "1234000"

Second response

HTTP/1.1 304 Not Modified
ETag: "1234000"

Third request

GET /news.html HTTP/1.1
Host: example.com
If-None-Match: "1234000"

Third response

HTTP/1.1 200 OK
ETag: "1234001"
Content-Type: text/html
Content-Length: 1600

<message body contains requested resource>

Code references

.NET

HttpStatusCode.NotModified

Rust

http::StatusCode::NOT_MODIFIED

Rails

:not_modified

Go

http.StatusNotModified

Symfony

Response::HTTP_NOT_MODIFIED

Python3.5+

http.HTTPStatus.NOT_MODIFIED

Java

java.net.HttpURLConnection.HTTP_NOT_MODIFIED

Apache HttpComponents Core

org.apache.hc.core5.http.HttpStatus.SC_NOT_MODIFIED

Angular

@angular/common/http/HttpStatusCode.NotModified