-1

I wrote a simple Express node.js server to test out some HTTP caching stuff.

const express = require('express')
const serveStatic = require('serve-static')
const path = require('path')

const app = express()

app.use(serveStatic('build', {
  extensions: ['html'],
  setHeaders(res, path) {
    res.setHeader('Cache-Control', `max-age=10`)
  }
}))
app.get('*', function (request, response) {
  response.sendFile(path.resolve(__dirname, 'build/200.html'))
});

const port = process.env.PORT || 3001
app.listen(port, () => console.log(`Listening on port ${port}`))

Interestingly without me explicitly adding ETAG with res.setHeader, it seems like the response automatically comes with a weak ETAG something like ETag: W/"45b4e-181a6ae36a4". However, if I explicitly set the ETAG myself, e.g. res.setHeader('ETAG', md5(...)) then no weak ETAG occurs.

I wonder where weak-etag comes from and how that affects the cache invalidation. Would it behave the same as if I explicitly set the ETAG myself?

Here is a similar question on here but the answer there doesn't seem to apply to my case.

Joji
  • 4,703
  • 7
  • 41
  • 86
  • Does this answer your question? [how does a etag work in expressjs](https://stackoverflow.com/questions/24542959/how-does-a-etag-work-in-expressjs) – Joe Jul 01 '22 at 10:36
  • 1
    @Joe no it doesn't. My question is not about how etag works but why express sometimes use weak etag and sometimes it doesn't. Totally different question. – Joji Jul 01 '22 at 15:19

1 Answers1

3

res.sendFile and res.send, on which it is based, generate their own ETag, unless an ETag header has already been set. See https://github.com/expressjs/express/blob/158a17031a2668269aedb31ea07b58d6b700272b/lib/response.js#L178-L180

And the default ETag function is "weak". See https://github.com/expressjs/express/blob/158a17031a2668269aedb31ea07b58d6b700272b/lib/application.js#L80-L86

Clients treat ETags as "opaque": they are received from the server in an ETag header when a resource is read and are send back to the server in a subsequent request

  • in the If-Match header when the resource is updated
  • in the If-Match-None header when the resource has been cached and is revalidated.

It depends on the server implementation whether the ETag matches and, hence, whether the resource can be updated or the cached resource be used. The server also decides whether to send a weak or a strong ETag in the first place.

Heiko Theißen
  • 12,807
  • 2
  • 7
  • 31
  • thanks! how does this `weak` / `strong` influence the caching overall? – Joji Jul 02 '22 at 18:58
  • See https://developer.mozilla.org/en-US/docs/Web/HTTP/Conditional_requests#validators – Heiko Theißen Jul 02 '22 at 19:05
  • so if two weak etag match, whether the client would reuse the cache depends on the implementation of the server right? – Joji Jul 02 '22 at 19:18
  • Yes, see my augmented answer. – Heiko Theißen Jul 03 '22 at 13:35
  • sorry I guess I didn't make myself clear, I was asking that if weak ETags match, whether it becomes a cache hit or miss depending on the server's implementation? like the server would send a 304 (cache hit) or a full response with 200? I guess for strong ETags it's most likely to be a 304 right? – Joji Jul 03 '22 at 18:13
  • Yes, the server decides whether to respond with 304. Could also be for weak etags, depending on the type of resource. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Conditional_requests#weak_validation – Heiko Theißen Jul 03 '22 at 18:28
  • check this it might help you https://stackoverflow.com/questions/27494948/express-etag-always-changing – PK2995 Jul 04 '22 at 05:27
  • @Joji "sorry I guess I didn't make myself clear..." you should ***really*** update your question if you are looking for more specificity. Your question does not reflect some of the specifics you seem to be looking for, and you have yet to accept a solution that *seems* to address your OG questions – Randomness Slayer Jul 09 '22 at 16:47