从学习前端开始就有人跟我说要看http相关内容,也有很多的内容,有很多可以优化的地方。
但一直没有静下心来去看这个内容,现在感觉是时候该自己做一个小小的总结了。
关于web缓存的优点很明显,大致的总结就是
减少网络带宽消耗、
降低服务器压力、
减少网络延迟,加快页面打开速度。
首先,我从什么场景会用到这个web缓存来讲。
1、从URI输入地址回车进入;2、F5或comman+R刷新页面;3、ctrl+F5强制刷新页面。
例如在做以上三个动作之前,已经进入过这个页面请求时为设置任何缓存信息,即之后第二次进入(有缓存可能性)的情况下进行:
Cache-Control:max-age=31104000 //缓存有效时长
Expires:Thu, 20 Jul 2017 02:18:41 GMT //缓存有效期截止时间
Last-Modified:Fri, 15 Jul 2016 04:11:51 GMT //最近一次服务器数据变更时间
第一次请求后返回关于缓存的信息。
1、从URI输入地址回车进入:会重新加载一些资源,例如图片等等。
请求发起时带了以上的信息,浏览器判断是否有缓存以及缓存有效期(Cache-Control或Expires,前者优先与后者)。
可看到请求状态为 200 OK (from cache)表示浏览器未发送请求到服务器,直接读取浏览器缓存内容。
2、F5或comman+R刷新页面:会重新加载一些资源,例如图片等等。
请求发起时依然带上一样的信息,但浏览器忽略浏览器缓存有效期(Cache-Control或Expires)等信息,一定会发起请求到服务器。服务器收到请求后,根据If-Modified-Since:Fri, 15 Jul 2016 04:11:51 GMT 或是Etag(其作用与Last-Modified类似,只是方式不同,Etag为一段MD5加密后的标志符,
优先级高于Last-Modified(请求时为If-Modified-Since);
对于分布式服务器有劣势,因不同服务器其数据即使没改变也是不同的Etag从而重复获取同样的数据,浪费资源)
判断服务器在从If-Modified-Since之后是否有修改过数据,如没修改则返回状态码 304 让浏览器读取浏览器缓存内容。该字段只能精确到秒级,如果1秒内多次修改
数据则无法标注文件新鲜度。
3、ctrl+F5强制刷新页面:不管任何缓存信息,所有数据都从服务器获取最新数据。
PS:优先级:Cache-Control > Expires > If-Modified-Since.
有人可能会问,那是否有Cache-Control的时候If-Modified-Since是否多余了呢?
答案是否定的,可参见以上场景2,即刷新页面时,会忽略Cache-Control或Expires,一定会发起请求到服务器,这时
If-Modified-Since就派上用场了。
用户操作 | Last-Modified/ETag | Cache-Control/Expires |
---|---|---|
URI地址回车 | 有效 | 有效 |
页面链接跳转 | 有效 | 有效 |
新建页面 | 有效 | 有效 |
前进后退 | 有效 | 有效 |
F5刷新 | 无效 | 有效 |
Ctrl+F5强制刷新 | 无效 | 无效 |
同时存在 | 优先级低 | 优先级高 |
HTTP请求流程
以下场景均不能做浏览器缓存:
- HTTP信息头中包含Cache-Control:no-cache,pragma:no-cache,或Cache-Control:max-age=0等告诉浏览器不用缓存的请求
- 需要根据Cookie,认证信息等决定输入内容的动态请求是不能被缓存的
- 经过HTTPS安全加密的请求,也存在例外情况
- POST请求无法被缓存
- HTTP响应头中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的请求无法被缓存