那些年被忽略的——HTTP的缓存

152 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第19天,点击查看活动详情

  • HTTP/1.1协议有很多策略来让缓存生效从而提升性能
  • 使用缓存可以在一些情况下不发送请求,具体是
    • 利用过期机制,减少访问次数
    • 使用验证机制,减少网络带宽
  • HTTP/1.1允许服务器、缓存和客户端在必要的时候能显式地降低透明度 1、当通信所有方需要时,提供了完全语义上的透明度的特性 2、允许源服务器或用户代理显式地请求和控制非透明操作的协议特性 3、允许缓存给响应绑定警告信息

正确的缓存

  • 一个正确的缓存必须能用缓存里最新的响应来响应请求,已缓存的响应必须满足:
    • 已缓存的响应和当前情况下,通过源服务器返回的响应一样
    • 已缓存的响应要足够的新
    • 已缓存的响应可以是响应码为304、305、或者4xx、5xx的响应
  • 如果缓存不能和源服务器通信,那么缓存必须返回一个错误或警告提示通信失败

警告信息

  • warning头部可能被用于缓存或其他的目的,使用warning头部还是错误码在于是否是真正的错误
  • 警告是三位数字的警告码,第一个数字代表在一个成功的重验证之后,警告是否必须从缓存项里删除
    • 1xx警告描述了响应的保鲜或重验证状态,并且这些状态必须在一个成功的重验证之后删除。可能是由缓存产生的,客户端不能生成1xx的警告码
    • 2xx警告描述了实体主体或实体头部的某些方面的信息,这些信息不能被重验证修改,并且这些信息不能在重验证成功后删除
  • 多个警告可能会绑定一个响应,并且多个警告可以共用一个警告码
  • 当多个警告绑定一个响应时,有时候不会把所有的警告都展示给客户

缓存控制

  • http/1.1基本缓存机制即服务器指定过期时间和验证对缓存是隐式指令,服务器或客户端可能需要给HTTP缓存提供显示执行,用cache-control头部来实现
  • Cache-control头部允许客户端或服务器在请求或响应里传输多个指令,这些指令常常覆盖缺省的缓存算法。如果头部值中存在一个明显的冲突,那么会使用最大程度可以严格解释的值

显式用户代理警告

  • 很多用户带来允许用户覆盖基本缓存机制
    • 用户代理允许用户指定缓存实体,即使实体显而易见不是最新的,也不要被验证
    • 比如用户代理给所有请求加上Cache-Control:max-state=3600
  • 如果用户覆盖了基本缓存机制,那么用户代理无论何时遇到不能满足服务器透明度要求的信息被展现时,用户代理应该显式的给用户提示和警告
  • 如果用户覆盖了基本缓存机制,但是新的机制可能降低了缓存效率,那么用户代理应该给用户提示呵呵警告,让用户谨慎消费额外资源或者忍受额外延迟

规则和警告的特殊情况

  • 某些情况下,缓存的操作者可以选择设置返回老旧的响应,即使这个响应没有被客户端请求。缓存利用warning头部会给这个响应做个标记
  • 但是可以允许用户代理去获取最新的响应,如果客户端要请求最新的响应,缓存就不应该返回一个老旧的响应

客户端控制的行为

  • 当源服务器是过期信息的主要来源时,在某些情况下,客户端可能需要控制缓存决定是否返回一个已缓存的响应而不需要服务器验证,客户端通过利用cache-control头部的一些指令来实现这个需求
  • 客户端的请求可能会指定一些超过设置的最大期限并且没有被验证的响应,指定0会强迫缓存重验证所有的响应。
  • 客户端也可能会愿意接受一些老旧的响应,虽然可能违反了源服务器对予以透明的闲置,但是可以支持脱机操作,或者连接不好时的高可用性

总结

  • 缓存是用来提供性能的,能让源服务器和客户端有效沟通,同时对用户的使用体验也有很大的提升。