在一次http请求过程当中,http缓存主要涉及到三个角色:浏览器、浏览器缓存和服务端。如下咱们按照一次http请求的顺序,讨论下不一样状况下缓存的表现。html
浏览器-浏览器缓存(强制缓存)
1. 浏览器是否有缓存?
安装浏览器时,会生成一个存放缓存的文件夹。此文件夹中包含了各缓存资源和资源的相关信息(好比url、expire time等)。若是有此资源的缓存记录,则表示有缓存;没有则表示没有缓存。
查看缓存文件的方法以下:chrome
mac下目录:/Users/XXX/Library/Caches/Google/Chrome/Default/Cache
windows下目录
C:\Users\{用户名}\AppData\Local\Google\Chrome\User Data\Default\Cache
打开文件夹,能够看到里面保存着许多文件,这些都是缓存的资源,可是都是通过编码的,且咱们不知道文件类型,所以没法查看。windows下有个工具能够帮忙查看。windows

里面清晰的包含了每条缓存的相关信息(这些信息保存在cache文件夹下的index文件中),包括url、file size、expire time、cache control等。选中一条记录,按F7能够直接查看当前缓存资源、按F4能够查看并保存当前缓存资源。浏览器
2. 浏览器缓存是否过时
若是请求的资源有缓存,则浏览器会判断缓存是否过时,主要经过如下两个字段:缓存
- expire:值为一个绝对时间,表示资源过时的时间。若是当前时间大于此值,则表示已过时,反之未过时。expire是HTTP1.0标准下的字段。
- cache-control:HTTP1.1标准下的字段。
max-age:值为一个单位为毫秒的时间段,表示资源在***毫秒后过时
must-revalidate
经过以上判断,若是缓存未过时,则直接采用缓存资源,并返回200(for cache);若缓存已过时,则要从新像服务端请求最新的资源。服务器
【expire和cache-control的关系】工具
- 若是请求中同时存在二者expire和cache-control:max-age,则expire将被忽略
- expire为绝对时间,这一依赖于客户端与服务端的时间保持一致,若客户端时间出错,将会判断有误;max-age为相对时间,不会出现此问题
【no-cache与no-store】
no-cache与no-store在客户端和服务端上表明的意义不同,要分开来讲。编码
- 在服务端响应中:no-cache表示浏览器能够对资源进行缓存,可是每次使用资源时不能直接使用,必须从新请求(也就是采用西面讲到的协商缓存);no-store不容许浏览器对资源进行缓存,也就是客户端根本不会存在此资源的缓存文件。从上面的记录中的cache-control也能看出来,只会出现no-cache,不会出现no-store,由于no-store的资源压根不会被缓存,也就不会出如今缓存记录中
- 在客户端请求中:no-cache表示这次请求不采用缓存文件(即便有缓存),须要要服务端请求,返回200。(ctrl+F5强制刷新时,就是讲cache-control设置为no-cache)做用至关于服务端响应中的no-store
【客户端no-cache和max-age=0】url
no-cache表示必须从新像服务端请求资源,返回200;max-age=0表示在从新获取资源以前,先检验ETag/Last-Modified,返回304.net
浏览器-服务端(协商缓存)
当浏览器没有缓存时,浏览器将像服务端发起请求。此时服务端也不直接返回新资源,会先看看客户端的资源是否已是最新资源。
- 在上一次请求的响应中,服务端的response headers中会包含last-modified和etag(能够在上面提到的缓存记录中看到),当客户端再次发起请求时,会在request headers中带上 if-modified-since(对应last-modified的值)和if-none-match(对应etag的值)
- if-modified-since:服务端对比发过来的if-modifind-since和服务端的last-modified,若是时间一致,表示至上次请求后,服务端上此资源未修改过,浏览器可使用缓存中的数据。相应状态码304,
- if-none-match:服务端对比发过来的if-none-match和服务端的etag,若是相等,表示至上次请求后,服务端上此资源未修改过,浏览器可使用缓存中的数据。相应状态码304
【last-modified与etag的关系】
- last-modified只能精确到秒,若文件修改的一秒内修改屡次,last-modified没法判断
- 有些资源会周期性的更新,但内容不必定变(仅最后修改时间last-modified变化),此时咱们认为此资源未被修改,而last-modified会发生变化,etag(通常此类周期性更新的资源,etag中不依赖最后修改时间)未发生变化
- 某些服务器不能精确的获得文件的最后修改时间