HTTP 缓存原理与实践
前言
科学正确的使用 Http 缓存,会让我的应用体验上升一次台阶,并有效的节约服务器资源。
了解 Http 缓存机制与原理,并使用在自己的应用中。下文内容提供详细参考。
一、HTTP缓存相关请求头
- Cache-Control
- Expires
- Etag
- Last-Modified
- If-None-Match
- If-Modified-Sign
二、强缓存
- 第一次请求资源
服务器 Response Header 返回
- Cache-control 资源缓存时间 6s (强缓存)
- Etag 资源 etag 摘要(协商缓存)
- Last-Modified: 资源最后修改时间 (协商缓存)
- 第二次请求资源
在 6s 内刷新了页面,重新加载图片,由于第一次请求设置了 Cache-Control 缓存时间为 6s。
于是图片直接从内容中加载(from memory cache)
如果 6s 内关闭页面重新打开会看到缓存内容从硬盘中加载(from dist cache)
Cache-Control,Expires 等强缓存字段都可由服务器返回。(Node, Nginx, Java 等等)
下文会记录 Node 处理方式。
三、协商缓存
接着强缓存的流程,图片加载 6s 后刷新重新页面,图片超过了强缓存设置的时间,浏览器会向服务器发起资源请求。
Request Header 中携带第一次加载图片时服务器返回的字段:
If-Modified-Sign 设置服务器上次请求返回的 Last_Modified
If-Nono_Match 设置服务器上次请求返还的 Etag
服务器端
判断请求头 Request Header 是否携带 If-Modified-Sign、If-Nono_Match。如果存在,通过计算获取资源的 etag,与请求头的 etag 进行对比,If-Modified-Sign 与文件的最后修改时间对比,如果都匹配,直接返回 304 给浏览器。浏览器直接加载本地资源。如果不匹配,则返回资源数据给浏览器。
If-Modified-Sign、If-Nono_Match 同时存在时,If-Nono_Match 的优先级更高。也就是 就算 If-Modified-Sign 与目标资源的最后修改时间不同,但是 etag 值相同,那么也直接返回 304,也就是走协商缓存。
四、Koa 静态资源处理
-
添加静态资源包依赖库
koa-static
npm install koa-static
- 启动静态资源服务器
javascriptconst Koa = require('koa'); const static = require('koa-static'); const App = new Koa(); App.use(static('../public')) App.listen(3000);
- 处理强缓存请求头
javascript/** Browser cache max-age in milliseconds. (defaults to 0) */ maxage?: number; /** Tell the browser the resource is immutable and can be cached indefinitely. (defaults to false) */ immutable?: boolean; /** Allow transfer of hidden files. (defaults to false) */ hidden?: boolean; /** Root directory to restrict file access. (defaults to '') */ root?: string; /** Name of the index file to serve automatically when visiting the root location. (defaults to none) */ index?: string | false; /** Try to serve the gzipped version of a file automatically when gzip is supported by a client and if the requested file with .gz extension exists. (defaults to true). */ gzip?: boolean; /** Try to serve the brotli version of a file automatically when brotli is supported by a client and if the requested file with .br extension exists. (defaults to true). */ brotli?: boolean; /** If not false (defaults to true), format the path to serve static file servers and not require a trailing slash for directories, so that you can do both /directory and /directory/. */ format?: boolean; /** Function to set custom headers on response. */ setHeaders?: SetHeaders; /** Try to match extensions from passed array to search for file when no extension is sufficed in URL. First found is served. (defaults to false) */ extensions?: string[] | false;
-
处理协商缓存
npm install koa-conditional-get
npm install koa-etag
javascriptconst Koa = require('koa'); const path = require('path'); const conditional = require('koa-conditional-get'); const etag = require('koa-etag'); const App = new Koa(); App.use(conditional()); App.use(etag()); App.use(static('../public')) App.listen(3000);