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.
CodePudding user response:
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.