browser: can haz foo?
GET /foo HTTP/1.1
server: o hai, dis version 12345.
note, there's always an empty line between headers & body.
HTTP/1.1 200 OK
ETag: "12345"
<!doctype html><p>foo.
browser: hai. can haz latest? i haz 12345.
GET /foo HTTP/1.1
If-None-Match: "12345"
server: u haz latest lol!
HTTP/1.1 304 Not Modified
if page has changed + new version is 56789,
server: lol wut! herez latest
HTTP/1.1 200 OK
ETag: "56789"
<!doctype html><p>new foo.
GET requests with If-None-Match
headers are called conditional GET requests, since the server only returns a response body if there's new content. You can also use date-based validation to issue conditional GETs, saving transfer bandwidth without implementing ETags. The flow is the same, except the server sends down an Expires
date, and the browser sends it back as a Last-Modified
header.
See the HTTP 1.1 RFC for more details. It's more readable than you'd think.
Also, those are valid html5 documents in the examples; I just omitted optional tags.
@llimacruz - It's up to your code to do pre-work to determine if changes were made. How you do this will be up to your own application's implementation, but you're going to need to assemble the data that was used to create the etag in the prior response to determine if it matches.
At minimum, etags allow you to save the time of sending a (potentially large) response back to the server, even if you still have to do the same amount of "work" on the server requesting resources, etc... This can be very fast if you're using effectively server-side caching though, since you'll just be hitting your caching layer instead of going to your database.