从零开始搭建一个Koa服务器来一步一步理解浏览器的缓存机制

本文详细介绍了如何从零开始搭建一个Koa服务器来一步一步理解浏览器的缓存机制

本文代码地址:koa-http

建议将代码拉下来之后,配合本文一起查看,效果更佳。

## 搭建本地服务器

1、新建文件夹并进入,命名为:http

mkdir http && cd http

2、初始化 package.json 文件,默认已经安装 node 以及 npm(如需安装 yarn,执行 npm install -g yarn)

yarn init 按照提示填写项目基本信息

3、安装相关依赖

yarn add koa koa-router fs-extra path mime crypto nodemon

4、在 http 目录下创建 src

index.js 入口文件,index.html 首页源代码,source.jpg 和 style.css 是 index.html 用到的图片和样式。

index.html

style.css

index.js

运行代码

yarn start

访问页面如下:

当前服务器没有配置缓存,可以看到size部分显示了资源的大小。如果是命中强缓存就会显示from memory cache或from disk cache


## 强缓存

强缓存是浏览器在本地判定缓存是否有过期,未过期直接从内存和磁盘读取缓存,整个过程不需要和服务器通信,返回的状态码是200。

HTTP 1.0

expires

expires是HTTP1.0中定义的缓存字段,当我们请求一个资源,服务器返回时,可以在Response Headers中增加expires字段表示资源的过期时间。它是一个时间戳,当客户端再次请求该资源的时候,会把客户端时间与该时间戳进行对比,如果大于该时间戳则已过期,否则直接使用该缓存资源。但会有问题,发送请求时是使用客户端时间去对比。一是客户端和服务端时间可能快慢不一致,另一方面是客户端的时间是可以自行修改的(比如浏览器是跟随系统时间的,修改系统时间会影响到),所以不一定满足预期。

修改 src/index.js 中处理图片的路由,在响应头中加上了 expires 字段,过期时间为 2 分钟后。

第一次访问:

2 分钟内再次刷新页面,Status Code 会显示from memory cache

HTTP1.1

cache-control

HTTP1.1新增了cache-control字段来解决HTTP1.0 expires存在的问题,当cache-control和expires都存在时,cache-control优先级更高。

1、响应头添加 cache-control: no-cache,即不允许使用强缓存。

设置了 cache-control: no-cache 后,每次刷新都是下面截图一样,浏览器不再使用缓存,如果使用了缓存Status Code 部分有说明。得出结论 cache-control 确实优先级比 expires 高。

2、设置 cache-control: max-age=60,缓存1分钟后失效。

第一次访问:

1 分钟内再次刷新页面,Status Code 会显示from memory cache

## 协商缓存

协商缓存需要向服务器发送一次协商请求,请求时带上和协商缓存相关的请求头,由服务器判断缓存是否过期,未过期就返回状态码304,浏览器当发现响应的返回码是304就直接读取本地缓存,如果服务器判定过期就直接返回请求资源,状态码为200。

Last-Modified / If-Modified-Since

Last-Modified是服务器响应请求时,返回该资源文件在服务器最后被修改的时间。

If-Modified-Since则是客户端再次发起该请求时,携带上次请求返回的Last-Modified值,通过此字段值告诉服务器该资源上次请求返回的最后被修改时间。服务器收到该请求,发现请求头含有If-Modified-Since字段,则会根据If-Modified-Since的字段值与该资源在服务器的最后被修改时间做对比,若服务器的资源最后被修改时间大于If-Modified-Since的字段值,则重新返回资源,状态码为200;否则则返回304,代表资源无更新,可继续使用缓存文件。

第一次访问:

再次刷新页面,Status Code 为304

Etag / If-None-Match

Etag是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成)。

f-None-Match是客户端再次发起该请求时,携带上次请求返回的唯一标识Etag值,通过此字段值告诉服务器该资源上次请求返回的唯一标识值。服务器收到该请求后,发现该请求头中含有If-None-Match,则会根据If-None-Match的字段值与该资源在服务器的Etag值做对比,一致则返回304,代表资源无更新,继续使用缓存文件;不一致则重新返回资源文件,状态码为200。

第一次访问:

再次刷新页面,Status Code 为304

总结

强缓存优先于协商缓存进行,若强缓存(Expires和Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match),协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,重新获取请求结果,再存入浏览器缓存中;生效则返回304,继续使用缓存。

文章及代码中如有问题,欢迎指正,谢谢!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342