博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HTTP缓存
阅读量:7239 次
发布时间:2019-06-29

本文共 1965 字,大约阅读时间需要 6 分钟。

  缓存的重要性不言而喻,通过网络请求资源缓慢并且降低了客户端的用户体验,增加了服务器的负担。很多短期内不会经常发生变化的资源文件没必要每次访问都向服务器进行数据请求,而缓存策略的使用就是为了改善客户端的呈现时间,降低服务器的负担。

对于HTTP缓存机制来说,策略体现在HTTP头部信息的字段上,这些策略根据是否需要重新向服务器端发起请求可以分为强缓存协商缓存两大类。

强缓存:

强缓存紧密连接着一个缓存时间期限,浏览器请求资源时会查看缓存中的资源是否存在并确定该缓存资源是否已过期,若没有过期,则取得缓存中的资源。

协商缓存:

可见协商缓存无论如何都要与服务器进行交互,比强缓存稍微复杂些。但是两者是相辅相成并且可以共存的,强缓存优先级较高,意味着请求一个资源时会先比较强缓存中的字段,如果命中则不会再执行接下来的协商缓存的过程。

1、强缓存

与强缓存相关的HTTP header的字段有两个Expires以及Cache-Control

Expires是HTTP1.0的规范,且客户端与服务器的时间会有误差,因此使用HTTP1.1的Cache-Control来替代Expires.

(1)Expires

该字段规定了缓存的资源的过期时间,在此之前,缓存中的资源都是有效的。如Tue, 27 Feb 2018 06:37:48 GMT,它的时间期限是服务器生成的,与客户端的时间会存在误差,固定时间,是HTTP1.0时的规范。优先级比cache-control低。

(2)Cache-Control

其中最常用的max-age单位为秒,对比expires体现着一个相对时间,即多少秒后缓存资源失效。

例如:

图中Cache-Control仅指定了max-age,所以默认为private,缓存时间为31536000秒(365天)

也就是说,在365天内再次请求这条数据,都会直接获取缓存数据库中的数据,直接使用。

需要注意的一点是:no-cache不是说不准使用缓存,而是需要走接下来优先级相对较低的另一类--协商缓存。真正决定不用缓存内的资源的是字段no-store

2、协商缓存

协商缓存是通过客户端与服务器进行HTTP通信时,互送缓存标识。

缓存标识可以分为两种:

  • Last-Modefied和if-Modefined-Since

第一次请求某个资源时,由于一定不会走缓存,所以服务器端会在响应头中加上一个形如:Last-Modified:Mon, 26 Feb 2018 06:37:41 GMT的字段告诉客户端,这个资源上次最后修改的时间。当刷新页面再次请求时,这时候的协商缓存会在请求头中加上一个形如:If-Modified-Since:Mon, 26 Feb 2018 06:37:41 GMT的字段。判断上一次时间后是否修改了,让服务器去判断是否在此时间后资源内容发生了变化。

若资源的Last-Modified大于If-Modified-Since,说明资源又被改动过,则响应整片资源内容,返回状态码200;

若资源的Last-Modified小于或等于If-Modified-Since,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。

如果服务器端发现资源改变了,就返回200以及新的资源给客户端,若没有修改,返回304 Not Modified 让客户端从缓存中取。

 

  • Etag和if-None-Match

同样第一次客户端请求资源时,服务端随资源在响应头部返回一个字段Etag,形如: ETag:W/"1823823287"。该字段的值是该资源在服务器端的唯一标识,生成Etag的策略由服务器决定。当资源发生变化时该值也发生变化。下一次客户端请求同一资源时,在请求头将这次得到的值放在字段if-None-Match中发送给服务端

如果服务器端发现资源改变了,就返回200以及新的资源给客户端,若没有修改,返回304 Not Modified 让客户端从缓存中取。

 

上述两个方式中,
Etag 和 If-None-Match的优先级要高于Last-Modified 和 If-Modified-Since,进而会衍生出一个思考,二者相比功能相同,但是表达形式决定了 Etag 解决了 Last-Modified 存在的一些问题,比如Last-Modified 是比较时间,精确到秒,若是
毫秒级的改变则没法兼顾,存在着周期性更改的资源,然而有可能
资源本身的内容并没有改变,那如果重新请求响应意义并不是那么的大。所以不难理解Etag具有高优先级有他的合理之处。

 

转载于:https://www.cnblogs.com/xiaoan0705/p/10497099.html

你可能感兴趣的文章
linux操作系统中oracle数据库的密码过期问题解决
查看>>
Spring中Bean的五个作用域
查看>>
hadoop之 distcp(分布式拷贝)
查看>>
Java后端程序员1年工作经验总结
查看>>
使用Vundle管理配置Vim的插件
查看>>
JDBC连接池&DBUtils使用
查看>>
可以通过shadowserver来查看开放的mdns(用以反射放大攻击)——中国的在 https://mdns.shadowserver.org/workstation/index.html...
查看>>
IOS系统控件高度
查看>>
Flink - ResultPartition
查看>>
2017.10.09 穆瑞课KUKA机器人培训视频的感想
查看>>
Jsoup
查看>>
python中的中文编码问题
查看>>
安卓播放音频
查看>>
in linux system of ftp command
查看>>
Win API:之GetCurrentThread、GetCurrentThreadId、GetCurrentProcess、GetCurrentProcessId
查看>>
***PHP $_FILES函数详解 + PHP文件上传 move_uploaded_file() 参数的正确写法
查看>>
Mysql中Group By使用Having语句配合查询(where和having区别)
查看>>
C#连接数据库
查看>>
重定向和管道的区别
查看>>
分层、链式分析、url、联系的长度
查看>>