http 缓存策略

浏览器第一次向一个web服务器发起http请求后,服务器会返回请求的资源,并且在响应头中添加一些有关缓存的字段如:Cache-Control、Expires、Last-Modified、ETag、Date等等。之后浏览器再向该服务器请求该资源就可以视情况使用强缓存和协商缓存。

强缓存:浏览器直接从本地缓存中获取数据,不与服务器进行交互,返回的状态码是 200。
协商缓存:浏览器发送请求到服务器,服务器判定是否可使用本地缓存,返回的状态码是 304。
联系与区别:两种缓存方式最终使用的都是本地缓存;前者无需与服务器交互,后者需要,返回的状态码不同。

强缓存

强缓存主要包括 expires 和 cache-control

expires

expires 是 HTTP1.0 中定义的缓存字段。当我们请求一个资源,服务器返回时,可以在 Response Headers 中增加 expires 字段表示资源的过期时间(他是一个绝对时间)。

它是一个时间戳(准确点应该叫格林尼治时间),当客户端再次请求该资源的时候,会把客户端时间与该时间戳进行对比,如果大于该时间戳则已过期,否则直接使用该缓存资源。

但是,发送请求时是使用的客户端时间去对比。客户端的时间是可以自行修改的,所以不一定满足预期。
expires: Thu, 03 Jan 2019 11:43:04 GMT

cache-control

为解决上面问题,HTTP1.1 新增了 cache-control 字段。所以当 cache-control 和 expires 都存在时,cache-control 优先级更高。
该字段是一个时间长度,单位秒,表示该资源过了多少秒后失效(相对时间)。当客户端请求资源的时候,发现该资源还在有效时间内则使用该缓存,它不依赖客户端时间。cache-control 主要有 max-age 和 s-maxage、no-cache 和 no-store ,public 和 private、等值。
cache-control: public, max-age=3600, s-maxage=3600
max-age 和 s-maxage
两者是 cache-control 的主要字段,它们是一个数字,表示资源过了多少秒之后变为无效。在浏览器中,max-age 和 s-maxage 都起作用,而且 s-maxage 的优先级高于 max-age。在代理服务器中,只有 s-maxage 起作用。 可以通过设置 max-age 为 0 表示立马过期来向服务器请求资源。
no-cache 协商缓存 走协商缓存策略(去服务器验证资源是否过期)
no-store 禁止缓存 去浏览器请求最新资源。

public 表示该资源可以被所有客户端和代理服务器缓存
private(默认值) 表示该资源仅能客户端缓存。当设置了 s-maxage 的时候表示允许代理服务器缓存,相当于 public

pragma

既然讲到了 no-cache 和 no-store,就顺便把 pragma 也讲了。他的值有 no-cache 和 no-store,表示意思同 cache-control,优先级高于 cache-control 和 expires,即三者同时出现时
pragma -> cache-control -> expires
pragma: no-cache

协商缓存

缓存规则

上面的 expires 和 cache-control 都会访问本地缓存直接验证看是否过期,如果没过期直接使用本地缓存,并返回 200。但如果设置了 no-cache 和 no-store 则本地缓存会被忽略,会去请求服务器验证资源是否更新,如果没更新才继续使用本地缓存,此时返回的是 304,这就是协商缓存。协商缓存主要包括 last-modified 和 etag。

last-modified==

记录资源最后修改的时间。启用后,请求资源之后的响应头会增加一个 last-modified 字段
last-modified: Thu, 20 Dec 2018 11:36:00 GMT
当再次请求该资源时,请求头中会带有 if-modified-since 字段,值是之前返回的 last-modified 的值,如:if-modified-since:Thu, 20 Dec 2018 11:36:00 GMT。服务端会对比该字段和资源的最后修改时间,若一致则证明没有被修改,告知浏览器可直接使用缓存并返回 304;若不一致则直接返回修改后的资源,并修改 last-modified 为新的值。

两个缺点:

  • 只要编辑了,不管内容是否真的有改变,都会以这最后修改的时间作为判断依据,当成新资源返回,从而导致了没必要的请求响应,而这正是缓存本来的作用即避免没必要的请求。
  • 时间的精确度只能到秒,如果在一秒内的修改是检测不到更新的,仍会告知浏览器使用旧的缓存。
etag

为了解决 last-modified 上述问题,有了 etag。 etag 会基于资源的内容编码生成一串唯一的标识字符串,只要内容不同,就会生成不同的 etag。启用 etag 之后,请求资源后的响应返回会增加一个 etag 字段,
etag: “FllOiaIvA1f-ftHGziLgMIMVkVw_”

当再次请求该资源时,请求头会带有 if-no-match 字段,值是之前返回的 etag 值,如:if-no-match:“FllOiaIvA1f-ftHGziLgMIMVkVw_”。服务端会根据该资源当前的内容生成对应的标识字符串和该字段进行对比,若一致则代表未改变可直接使用本地缓存并返回 304;若不一致则返回新的资源(状态码200)并修改返回的 etag 字段为新的值。

可以看出 etag 比 last-modified 更加精准地感知了变化,所以 etag 优先级也更高。
etag 存在的问题,每次生成标识字符串会增加服务器的开销。所以要如何使用 last-modified 和 etag 还需要根据具体需求进行权衡。

访问刷新分析

我们将访问和刷新分为以下三种情况:

  • 标签进入、输入url回车进入
  • 按刷新按钮、F5 刷新、网页右键“重新加载”
  • ctrl + F5 强制刷新

假设当前有这么一个 index 页面,返回的响应信息如下
cache-control: max-age=72000
expires: Tue, 20 Nov 2018 20:41:14 GMT
last-modified: Tue, 20 Nov 2018 00:41:14 GMT

1标签进入、输入url回车进入

1 因为没有no-cache,和no-store 所以走强缓存策略。cache-control优先级>expries
依次判断是否过期。没有过期走强缓存返回200(from cache)
2 若已经过期,走协商缓存。etag>last-modified 优先比较etag。但是这里没有etag。所以比较
last-modified。若没有改变,怎么去读取本地缓存返回304(not modified)
3 否则返回新资源。状态200(ok)。并更新返回响应last-modified值。

2按刷新按钮、F5 刷新、网页右键“重新加载”

这种情况下,实际是浏览器将 cache-control 的 max-age 直接设置成了 0,让缓存立即过期,直接走协商缓存路线。发送的请求头如下:
cache-control: max-age=0
if-modified-since: Tue, 20 Nov 2018 00:41:14 GMT

3、ctrl + F5 强制刷新

强制刷新的情况下,浏览器会强行设置 no-cache,强制获取最新的资源,就连 if-modified-since 等其他缓存协议字段都会被吃掉。此时发送的请求头如下:

cache-control: no-cache
pragma: no-cache

pragma>cache-control 都是no-cache。走协商缓存。没有etag也没有if-modified-since,所以走服务器。

注:

3XX 重定向

  • 301 Moved Permanently

    永久重定向,表示请求的资源已经永久的搬到了其他位置
    就是说资源已经被分配了新的URL

  • 302 Found
    临时重定向,表示请求的资源临时搬到了其他位置
    请求的资源临时被分配到了新的URL
    和301很像,只不过资源是临时移动,资源在将来可能还会改变

  • 303 See Other
    表示请求资源存在另一个URI,应使用GET定向获取请求资源
    303功能与302一样,区别只是303明确客户端应该使用GET访问

  • 304 Not Modified
    协商缓存,使用本地缓存

    4XX 客户端错误

  • 400 Bad Request
    表示请求报文存在语法错误或参数错误,服务器不理解
    服务器不应该重复提交这个请求
    需要修改请求内容后再次发送

  • 401 Unauthorized
    表示发送的请求需要有HTTP认证信息或者是认证失败了
    返回401的响应必须包含一个适用于被请求资源的WWW-Authenticate首部以质询用户信息
    浏览器初次接受401时,会弹出认证窗口

  • 403 Forbidden
    表示对请求资源的访问被服务器拒绝了
    服务器可以对此作出解释,也可以不解释
    想说明的话可以在响应实体的主体部分描述原因
    比如说你可能没有访问权限

  • 404 Not Found
    表示服务器找不到你请求的资源
    也有可能服务器就是不想给你然后骗你找不到(⊙ˍ⊙)
    而且大多服务器都是这么玩这个状态码的

      200 OK
      请求正常处理完毕
      204 No Content
      请求成功处理,没有实体的主体返回
      206 Partial Content
      GET范围请求已成功处理
      301 Moved Permanently
      永久重定向,资源已永久分配新URI
      302 Found
      临时重定向,资源已临时分配新URI
      303 See Other
      临时重定向,期望使用GET定向获取
      304 Not Modified
      发送的附带条件请求未满足
      307 Temporary Redirect
      临时重定向,POST不会变成GET
      400 Bad Request
      请求报文语法错误或参数错误
      401 Unauthorized
      需要通过HTTP认证,或认证失败
      403 Forbidden
      请求资源被拒绝
      404 Not Found
      无法找到请求资源(服务器无理由拒绝)
      500 Internal Server Error
      服务器故障或Web应用故障
      503 Service Unavailable
      服务器超负载或停机维护
    
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值