HTTP缓存机制
转自:https://www.cnblogs.com/ranyonsue/p/8918908.html
1.概览
Web 缓存大致可以分为:数据库缓存、服务器端缓存(代理服务器缓存、CDN 缓存)、浏览器缓存。
浏览器缓存也包含很多内容: HTTP 缓存、indexDB、cookie、localstorage 等等。这里我们只讨论 HTTP 缓存相关内容。
浏览器缓存主要是 HTTP 协议定义的缓存机制。
2.缓存过期机制
- 缓存命中率:从缓存中得到数据的请求数与所有请求数的比率。理想状态是越高越好。
- 过期内容:超过设置的有效时间,被标记为“陈旧”的内容。通常过期内容不能用于回复客户端的请求,必须重新向源服务器请求新的内容或者验证缓存的内容是否仍然准备。
- 验证:验证缓存中的过期内容是否仍然有效,验证通过的话刷新过期时间。
- 失效:失效就是把内容从缓存中移除。当内容发生改变时就必须移除失效的内容。
加载页面流程:
- 浏览器先根据这个资源的http头信息来判断是否命中强缓存。如果命中则直接加在缓存中的资源,并不会将请求发送到服务器,返回码200。
- 如果未命中强缓存,则浏览器会将资源加载请求发送到服务器。服务器来判断浏览器本地缓存是否失效。若可以使用,则服务器并不会返回资源信息,浏览器继续从缓存加载资源,服务器返回304重定向到浏览器缓存。
- 如果未命中协商缓存,则服务器会将完整的资源返回给浏览器,浏览器加载新资源,并更新缓存,返回200。
首次请求:
浏览器再次请求时:
强缓存可以认为没有过期的缓存,协调缓存指已过期但未被服务器修改的内容。
3.强缓存
命中强缓存时,浏览器并不会将请求发送给服务器。在Chrome的开发者工具中看到http的返回码是200,但是在Size列会显示为(from cache)。
强缓存是利用http的返回头中的Expires或者Cache-Control两个字段来控制的,用来表示资源的缓存时间。
3.1 Expires 绝对时间
缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点。
Expires是Web服务器响应消息头字段,代表资源的失效时间,是绝对是时间。
由于失效时间是一个绝对时间,所以当客户端本地时间被修改以后,服务器与客户端时间偏差变大以后,就会导致缓存混乱。所以出现了3.2 Cache-Control
3.2 Cache-Control选项指定相对时间
https://blog.csdn.net/u012375924/article/details/82806617,讲的不错。
请求中Cache-Control可选项:
在响应中使用Cache-Control 时,它可选的值有:
Cache-Control是一个相对时间,例如Cache-Control:3600,代表着资源的有效期是3600秒。
Cache-Control比Expires优先级高。
4.协商缓存
若未命中强缓存,则浏览器会将请求发送至服务器。服务器根据http头信息中的Last-Modify/If-Modify-Since或Etag/If-None-Match来判断是否命中协商缓存。如果命中,则http返回码为304,浏览器从缓存中加载资源。
4.1 Last-Modify/If-Modify-Since
浏览器第一次请求一个资源的时候,服务器返回的header中会加上Last-Modify,Last-modify是一个时间标识该资源的最后修改时间:
当浏览器再次请求该资源时,发送的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存。
如果命中缓存,则返回http304,并且不会返回资源内容,并且不会返回Last-Modify。由于对比的服务端时间,所以客户端与服务端时间差距不会导致问题。
既然有这个为什么还有4.2 ETag呢?
- 1. Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间;
- 2. 如果某些文件会被定期生成,修改时间变了,但内容没变,但Last-Modified却改变了,导致文件没法使用缓存;
- 3.有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形。
4.2 ETag/If-None-Match
Etag/If-None-Match返回的是一个校验码(ETag: entity tag)。ETag可以保证每一个资源是唯一的,资源变化都会导致ETag变化*。
ETag值的变更则说明资源状态已经被修改。服务器根据浏览器上发送的If-None-Match值来判断是否命中缓存。
5.总结
https://blog.csdn.net/u012375924/article/details/82806617
- 缓存开关是: pragma, cache-control。
- 缓存校验有:Expires,Last-Modified,etag。
从状态码的角度来看,它们的关系如下图:
总结:304就是在过期的但没有失效的情况下,协助缓存的结果。
相关文章
- 【Http协议】深入理解HTTP协议
- 学习yii2.0——数据缓存、片段缓存、页面缓存、http缓存
- 记1个低级错误:java.io.IOException: Server returned HTTP response code: 500 for URL: http://localhost:8769/accr/print
- 《HTTP权威指南》读书笔记:缓存
- Java基础之Nginx缓存
- Okhttp设置http缓存,在没有网络的情况下加载http缓存里面的内容
- Docker Dockerfile之镜像缓存
- Nginx 浏览器之HTTP缓存的那些事
- 读取缓存行的伪共享问题
- 使用apache的HttpClient进行http通讯,隐藏的HTTP请求头部字段是如何自动被添加的
- Atitit 微服务实践 艾提拉著 微服务主要解决几个问题负载均很 目录 1. 微服务的模式 http请求层 vs服务层1 1.1. Http vs 服务层优缺点1 2. 实现技术2
- Atitit.h5 web webview性能提升解决方案-----fileStrore缓存离线存储+http方案
- Redis 缓存 + Spring 的集成示例
- 使用 http-proxy 代理 SAP UI5 应用发起的 HTTP 请求
- App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Te
- 关于HTTP协议中的Date及缓存时间
- 缓存最关心的问题是什么
- USG防火墙分片缓存和长连接命令
- 002-spring cache 基于注解的缓存-02详细-Cacheable 、CachePut、CacheEvict、Caching、CacheConfig、EnableCaching、自定义
- 【问题解决】[kubelet-check] The HTTP call equal to ‘curl -sSL http://localhost:10248/healthz‘ failed wite
- HTTP隧道ABPTTS——加密型的http隧道,todo自己搭建一个玩玩
- HTTP===http首部字段
- 缓存算法(FIFO 、LRU、LFU三种算法的区别)
- Nginx配置之负载均衡、限流、缓存、黑名单和灰度发布
- Django之django-redis对数据进行简单缓存
- Redis进阶学习09---缓存同步
- Redis进阶学习07--分布式缓存--下
- Nginx_02_Nginx三大高级功能(Http缓存、数据压缩、跨域访问)
- Varnish开源高性能反代和缓存服务器——筑梦之路