Open YBFACC opened 4 years ago
我的完整代码
强缓存:状态码是200,服务器并不会收到请求,浏览器直接使用缓存。
协议缓存:服务器收到请求并进行比较处理,如果文件没有改变就返回状态码 304,否则加上 Haeder 标记、状态码 200 、并重新返回资源。
强缓存的优先级高于协议缓存
The Last-Modified是一个响应首部,其中包含源头服务器认定的资源做出修改的日期及时间。 它通常被用作一个验证器来判断接收到的或者存储的资源是否彼此一致。由于精确度比 ETag 要低,所以这是一个备用机制。包含有 If-Modified-Since 或 If-Unmodified-Since 首部的条件请求会使用这个字段。
Last-Modified
ETag
If-Modified-Since
If-Unmodified-Since
语法
Last-Modified: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT
引用MDN
缺陷
ETagHTTP响应头是资源的特定版本的标识符。这可以让缓存更高效,并节省带宽,因为如果内容没有改变,Web服务器不需要发送完整的响应。而如果内容发生了变化,使用ETag有助于防止资源的同时更新相互覆盖(“空中碰撞”)。
ETag: W/"<etag_value>" ETag: "<etag_value>"
if-modified-since
last-modified
ctx.res.setHeader('Cache-control', 'no-cache') const ifModifiedSince = ctx.req.headers['if-modified-since'] let stats = fs.statSync('./cache/png.png') let change_time = stats.mtime.toUTCString() if (change_time === ifModifiedSince) { ctx.res.writeHead(304) } else { ctx.res.setHeader('last-modified', change_time) ctx.type = 'image/png' ctx.res.writeHead(200) let img = fs.readFileSync('./cache/png.png') ctx.res.write(img, 'binary') ctx.res.end() }
与上次的步骤基本一致。
ctx.res.setHeader('Cache-control', 'no-cache') const ifNoneMatch = ctx.req.headers['if-none-match'] const hash = crypto.createHash('md5') let css = fs.readFileSync('./cache/test.css', 'utf-8') hash.update(css) const etag = `"${hash.digest('hex')}"` if (ifNoneMatch === etag) { ctx.res.writeHead(304) } else { ctx.res.setHeader('etag', etag) ctx.type = 'text/css' ctx.res.writeHead(200) ctx.res.write(css, 'binary') ctx.res.end() }
ctx.res.setHeader('Cache-control', 'no-cache') const ifNoneMatch = ctx.req.headers['if-none-match'] let stats = fs.statSync('./cache/png1.png') var mtime = stats.mtime.getTime().toString(16) var size = stats.size.toString(16) let change_time = 'W/' + `"${size}-${mtime}"` if (change_time === ifNoneMatch) { ctx.res.writeHead(304) } else { ctx.res.setHeader('etag', change_time) ctx.type = 'image/png' ctx.res.writeHead(200) let img = fs.readFileSync('./cache/png1.png') ctx.res.write(img, 'binary') ctx.res.end() }
页面的所有资源都被浏览器缓存了,协议缓存并没有给服务器发送请求,没有开启强缓存的资源也被缓存。
当你指定 Cache-control:no-store 时,每次还会请求资源。
Cache-control:no-store
一文读懂前端缓存
MDN
通过 koa2 服务器实践探究浏览器HTTP缓存机制
协议缓存
我的完整代码
与强缓存的对比
强缓存:状态码是200,服务器并不会收到请求,浏览器直接使用缓存。
协议缓存:服务器收到请求并进行比较处理,如果文件没有改变就返回状态码 304,否则加上 Haeder 标记、状态码 200 、并重新返回资源。
强缓存的优先级高于协议缓存
Header 一览
请求头 if-modified-since 和响应头 last-modified
The
Last-Modified
是一个响应首部,其中包含源头服务器认定的资源做出修改的日期及时间。 它通常被用作一个验证器来判断接收到的或者存储的资源是否彼此一致。由于精确度比ETag
要低,所以这是一个备用机制。包含有If-Modified-Since
或If-Unmodified-Since
首部的条件请求会使用这个字段。语法
引用MDN
缺陷
请求头 if-none-match 和响应头 etag
ETag
HTTP响应头是资源的特定版本的标识符。这可以让缓存更高效,并节省带宽,因为如果内容没有改变,Web服务器不需要发送完整的响应。而如果内容发生了变化,使用ETag有助于防止资源的同时更新相互覆盖(“空中碰撞”)。语法
引用MDN
测试
原生使用if-modified-since 和 last-modified
if-modified-since
if-modified-since
与最后一次时间进行比较。如果没有改变就返回 304 ,如果不一致则返回 200 并加上last-modified
告诉浏览器这个文件最后一次修改时间。原生使用请求头 if-none-match 和响应头 etag
与上次的步骤基本一致。
使用协议缓存还是强缓存?
前进后退的行为
页面的所有资源都被浏览器缓存了,协议缓存并没有给服务器发送请求,没有开启强缓存的资源也被缓存。
当你指定
Cache-control:no-store
时,每次还会请求资源。参考
一文读懂前端缓存
MDN
通过 koa2 服务器实践探究浏览器HTTP缓存机制