Search code examples
json-server

Identical HTTP GET has status 200 on first request but 304 after that


I'm confused with Status Code 304 "The HTTP 304 Not Modified client redirection response code indicates that there is no need to retransmit the requested resources", what does retransmit the requested resources refers to?

Context:

  1. I'm using JSON SERVER to mock the back-end
  2. Every time I request for the url the first time, it would be okay (200)
  3. The following requests would result to status 304

The description of HTTP 304 sounds very vague to me, why would it say there's no need to retransmit the requested resources when I didn't cache the data originated from db.json in the first place.

Client code:

fetch(`http://localhost:4000/profiles`)
    .then(res => res.json())
    .then(data => setProfiles(data));

Server log:

GET /profiles 200 1.970ms - - # The first request is status 200
GET /profiles 304 2.609ms - - # The subsequent requests are status 304
GET /profiles 304 2.951ms - -
GET /profiles 304 2.903ms - -
# ...

Solution

  • To rephrase "the HTTP 304 Not Modified client redirection response code indicates that there is no need to retransmit the requested resources":

    You request a resource (the data from /profiles) once, and the server sends you that data with a 200 OK status. Now when you request the same resource (/profiles) and its data hasn't changed from the first request, the server will respond with a 304 Not Modified since it assumes you already have the data — it hasn't been modified since the request that was 200 OK.

    You say you didn't cache the data in the first request but the server is assuming you would (like the MDN docs for 304 Not Modified say, "It is an implicit redirection to a cached resource") and is trying to save resources.

    You'll have to determine if it's best in your specific situation to

    • cache the first response,
    • read a possible Expires header and only rerequest after that moment in time, or
    • possibly omit an If-None-Match ETag header as to tell the server that you don't have a cached version of the resource to use