In your specific case, the node.js server is just telling the browser that it's cached version of socket.io.js
is not out of date, so just use the one it already has in the cache. This is normal expected browser behavior for cacheable files. If you clear your browser cache, the restart the browser, then repeat this test, the first time you load the file, you should see a 200 status (since the cache was empty, the browser will not issue a conditional GET request). After that, once the file is cached, you should get 304 again.
A description of the 304 return status is right here in the spec (and also the very first result in a Google search):
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5
10.3.5 304 Not Modified
If the client has performed a conditional GET request and access is
allowed, but the document has not been modified, the server SHOULD
respond with this status code. The 304 response MUST NOT contain a
message-body, and thus is always terminated by the first empty line
after the header fields.
The response MUST include the following header fields:
- Date, unless its omission is required by section 14.18.1
If a clockless origin server obeys these rules, and proxies and clients add their own Date to any response received without one (as already
specified by [RFC 2068], section 14.19), caches will operate
correctly.
- ETag and/or Content-Location, if the header would have been sent
in a 200 response to the same request
- Expires, Cache-Control, and/or Vary, if the field-value might
differ from that sent in any previous response for the same
variant
If the conditional GET used a strong cache validator (see section 13.3.3), the response SHOULD NOT include other
entity-headers. Otherwise (i.e., the conditional GET used a weak
validator), the response MUST NOT include other entity-headers; this
prevents inconsistencies between cached entity-bodies and updated
headers.
If a 304 response indicates an entity not currently cached, then the
cache MUST disregard the response and repeat the request without the
conditional.
If a cache uses a received 304 response to update a cache entry, the
cache MUST update the entry to reflect any new field values given in
the response.
So, in a nutshell it means that if the client did a conditional GET request, then the server can return 304 which means that the content has not been modified since it was last requested and this a way for the server to communicate that back to the client without sending the content back again. Basically, the client says "I'd like to know if you have a newer version of this content and here's the meta data on the version I already have. If you don't have a newer version than what I already have, then just return a 304, otherwise send me the newer version".
And, if you want more explanation on a "conditional GET request", you can read about that here: https://ruturajv.wordpress.com/2005/12/27/conditional-get-request/
More detail
If you clear your browser cache and then fetch socket.io.js
, you will see a 200 response status and a response header like this:
ETag: xxxxx
Then, the next time your browser requests that same file, it will send a conditional GET request with this header in the request:
If-None-Match: xxxxx
Where xxxxx
is the same string in both.
This is the browser telling the server that it already has a version of this file with a given ETag. The server then checks to see if it's version of the file is that ETag or not. If the ETag matches, then it returns 304. In this case, the ETag is used as a version number. In some cases, it is a hash of the file, but in the specific case of socket.io.js, it's actually a version number (since the server code knows intimately about that particular file).