乐闻世界logo
搜索文章和话题
HTTP 缓存原理与实践

HTTP 缓存原理与实践

乐闻的头像
乐闻

2022年06月18日 12:13· 阅读 367

前言

科学正确的使用 Http 缓存,会让我的应用体验上升一次台阶,并有效的节约服务器资源。

了解 Http 缓存机制与原理,并使用在自己的应用中。下文内容提供详细参考。

一、HTTP缓存相关请求头

  • Cache-Control
  • Expires
  • Etag
  • Last-Modified
  • If-None-Match
  • If-Modified-Sign

二、强缓存

  1. 第一次请求资源

image-20210127170717895

服务器 Response Header 返回

  • Cache-control 资源缓存时间 6s (强缓存)
  • Etag 资源 etag 摘要(协商缓存)
  • Last-Modified: 资源最后修改时间 (协商缓存)

  1. 第二次请求资源

image-20210127170827108

在 6s 内刷新了页面,重新加载图片,由于第一次请求设置了 Cache-Control 缓存时间为 6s。

于是图片直接从内容中加载(from memory cache)

如果 6s 内关闭页面重新打开会看到缓存内容从硬盘中加载(from dist cache)

Cache-Control,Expires 等强缓存字段都可由服务器返回。(Node, Nginx, Java 等等)

下文会记录 Node 处理方式。

三、协商缓存

image-20210127170423785

接着强缓存的流程,图片加载 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 静态资源处理

  1. 添加静态资源包依赖库 koa-static

    npm install koa-static

    1. 启动静态资源服务器
    javascript
    const Koa = require('koa'); const static = require('koa-static'); const App = new Koa(); App.use(static('../public')) App.listen(3000);
    1. 处理强缓存请求头
    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;
    1. 处理协商缓存

    npm install koa-conditional-get

    npm install koa-etag

    javascript
    const 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);

五、刷新缓存失效情况

img

标签: