HTTP缓存

140 阅读6分钟

什么是HTTP缓存 ?

http缓存指的是: 当客户端向服务器请求资源时,会先抵达浏览器缓存,如果浏览器有“要请求资源”的副本,就可以直接从浏览器缓存中提取而不是从服务器中提取这个资源。

常见的http缓存只能缓存get请求响应的资源,对于其他类型的响应则无能为力,所以后续说的请求缓存都是指GET请求。

http缓存都是从第二次请求开始的。第一次请求资源时,服务器返回资源,并在响应头中回传资源的缓存参数;第二次请求时,浏览器判断这些请求参数,命中强缓存就直接200,否则就把请求参数加到请求头中传给服务器,看是否命中协商缓存,命中则返回304,否则服务器会返回新的资源。

http缓存的分类

根据是否需要重新向服务器发起请求来分类,可分为强制缓存,协商缓存;

根据是否可以被单个或者多个用户使用来分类,可分为私有缓存,共享缓存;

强制缓存如果生效,不需要再和服务器发生交互,而协商缓存不管是否生效,都需要与服务端发生交互

强缓存

强制缓存在缓存数据未失效的情况下(即Cache-Control的max-age没有过期或者Expires的缓存时间没有过期),那么就会直接使用浏览器的缓存数据,不会再向服务器发送任何请求。强制缓存生效时,在chrome控制台的Network选项中可以看到该请求返回200的状态码,并且size显示from disk cache或from memory cache两种。这种方式页面的加载速度是最快的,性能也是很好的,但是在这期间,如果服务器端的资源修改了,页面上是拿不到的,因为它不会再向服务器发请求了。

优先级:Cache-Control > Expires

协商缓存

当第一次请求时服务器返回的响应头中没有Cache-Control和Expires或者Cache-Control和Expires过期还或者它的属性设置为no-cache时(缓存,但是浏览器使用缓存前,都会请求服务器判断缓存资源是否是最新),那么浏览器第二次请求时就会与服务器进行协商,与服务器端对比判断资源是否进行了修改更新。如果服务器端的资源没有修改,那么就会返回304状态码,告诉浏览器可以使用缓存中的数据,这样就减少了服务器的数据传输压力。如果数据有更新就会返回200状态码,服务器就会返回更新后的资源并且将缓存信息一起返回。

优先级:Etag > Last-Modified

私有缓存(浏览器级缓存)

私有缓存只能用于单独的用户:Cache-Control: Private。

共享缓存(代理级缓存)

共享缓存可以被多个用户使用: Cache-Control: Public。

为什么要使用HTTP缓存 ?

  • 减少了冗余的数据传输,节省了网费。
  • 缓解了服务器的压力, 大大提高了网站的性能
  • 加快了客户端加载网页的速度

使用http缓存

浏览器第一次请求文件,服务器返回文件并约定过期时间Expires、文件最新修改时间Last-Modified,浏览器再次请求会判断文件是否超过了约定的过期时间Expires,时间没过,不发起请求,直接使用本地缓存,时间过期,浏览器带上了文件最新修改时间if-Modified-Since(也就是上次请求服务器返回的Last-Modified),服务器将if-Modified-SinceLast-Modified做了个对比,if-Modified-SinceLast-Modified不相等,服务器查找最新的文件,同时再次返回Expires与全新的Last-Modifiedif-Modified-SinceLast-Modified相等,服务器返回了状态码304,使用本地缓存。

max-age优先级要比Expires高,If-None-MatchEtag(上次服务器返回来的文件唯一标识符Etag)优先级比if-Modified-Since(也就是上次请求服务器返回的文件最新修改时间Last-Modified)高。

缓存字段

Cache-Control(请求/响应头)

  • no-store:所有内容都不缓存;
  • no-cache:缓存,但是浏览器使用缓存前,都会请求服务器判断缓存资源是否是最新,过期则返回最新的文件,没过期就使用缓存文件;
  • max-age=x(单位秒) 请求缓存后的X秒不再发起请求,属于http1.1属性,与Expires(http1.0属性)类似,但优先级要比Expires高;
  • s-maxage=x(单位秒) 代理服务器请求源站缓存后的X秒不再发起请求,只对CDN缓存有效;
  • public 客户端和代理服务器(CDN)都可缓存;
  • private 只有客户端可以缓存

Expires(响应头)

代表资源过期时间,由服务器返回提供,GMT格式日期,在这个绝对时间之前强缓存有效,是http1.0的属性,在与max-age(http1.1)共存的情况下,优先级要低。

Last-Modified(响应头)

标识的是资源在服务器上的最后修改时间,服务器会对比资源在最后修改时间之后是否有变动,有则返回新的资源,没有则返回304。

if-Modified-Since(请求头)

资源最新修改时间,由浏览器告诉服务器(其实就是上次服务器给的Last-Modified,请求又还给服务器对比),和Last-Modified是一对,它两会进行对比

Etag(响应头)

Etag 是由服务器为每个资源生成的唯一的标识字符串,这个标识字符串是基于文件内容编码的,只要文件内容不同,它们对应的 Etag 就是不同的,因此 Etag 能够精准地感知文件的变化。

if-None-Match(请求头)

缓存资源标识,由浏览器告诉服务器(其实就是上次服务器给的Etag),和Etag是一对,它俩会进行对比。

浏览器的不同行为对缓存的影响

  • 浏览器地址栏回车,或者点击跳转按钮,前进,后退,新开窗口,这些行为,会让Expires,max-age生效,也就是说,这几种操作下,浏览器会判断过期时间,再考虑要不要发起请求,当然Last-Modified和Etag也有效。
  • F5刷新浏览器,或者使用浏览器导航栏的刷新按钮,这几种,会忽略掉Expires,max-age的限制,强行发起请求,Last-Modified和Etag在这种情况下也有效。
  • CTRL+F5是强制请求,所有缓存文件都不使用,全部重新请求下载,因此Expires,max-age,Last-Modified和Etag全部失效。

action.png