HTTP缓存

来源:互联网 发布:windows键没反应 win10 编辑:程序博客网 时间:2024/06/03 16:38

HTTP缓存

你可能没有意识到它们的存在,可是它们确实是当代互联网一个举足轻重的概念。

基本概念

缓存大致可以分为两种:

  1. 应用级别的缓存,如APC(Alternative PHP Cache)、Memcache、Redis以及其他内存存储工具
  2. HTTP缓存-代理缓存(proxy)、网关缓存(gateway)、浏览器缓存

本文只谈论HTTP缓存的相关内容。

浏览器缓存,缓存的使用对象是个特定的用户。

代理缓存,是网络设施层面的缓存,所以涉及范围非常大,通常有大量的用户在使用。这类缓存通常由ISP或大公司来提供。

网关缓存,和代理缓存类似,也是面对大量用户的,但不同的是,网关缓存通常是为某个特定的网站服务的,它们通常架设在原始网站的前端。CDN服务就是给某一个网站在各地架设网关缓存,以此来提高用户对网站的访问速度。

HTTP缓存如何工作?

缓存系统会有一套特定的规则来决定是否使用缓存,其中一部分的规则是由公用协议(HTTP1.0和HTTP1.1)来规定的,另一部分是缓存管理者(浏览器的使用者或者缓存管理员)来决定的。

通常,这些规则如下:

  1. 如果响应头告诉缓存不要缓存,它就不会缓存
  2. 如果请求需要认证或者是安全链接(即HTTPS),则不会缓存响应
  3. 如果有以下情况,则一个资源就被认为是fresh的(新鲜的,即无需向原服务器验证就直接向客户端发送缓存资源):
    • 如果有过期时间或过期相关的头字段,并且在过期时间之内
    • 如果资源最近被请求过,并且资源只是在不久之前修改过
      这些情况下,资源直接从缓存返回客户端,原服务器完全不知情
  4. 如果一个资源是stale的(陈旧的),一般发起端就会去向原始服务器validate(即向原始服务器去验证,当前请求资源的缓存版本是否还是有效的)
  5. 在某些情况下,比如没联网的时候,缓存可能会向发起端提供比较陈旧的缓存版本
  6. 如果没有validator(验证的字段,如Etag或Last-Modified头字段),也没有任何freshness(新鲜度)的信息,则资源通常被认为是不能缓存的

新鲜度(freshness)和验证机制(validation)是缓存工作的两个重要概念。一个“新鲜”的资源会直接从缓存中获取,而验证机制确保在请求资源的时候如果资源未发生变化,则无需完整地再把资源发送一遍了。

如何操控缓存?

HMTL Meta 标签

在HTML的head里可以设置若干个这样的meta标签(详见相关引文1),这种方式的缺点是中间缓存代理可能压根不会去读取HTML的内容,所以这些缓存设置就不会被它们认可,一般这种设置方式只被浏览器认可,甚至是只有一部分浏览器才会认可。

Pragma头

很多人认为在响应头字段中加一个Pragma: no-cache就能让缓存不去缓存当前资源,但其实这不一定正确。HTTP的规范里并没有对响应字段里的Pragma做出说明,只有在请求头里讨论了一下,也就是说规范未对这种方式做出支持。虽然一小部分缓存系统会认可,但其他的并不是这样的。

Expires头

最基本最通用的一种方式,几乎所有缓存系统都支持。它指定了一个期限,过了这个期限之后,缓存就会向原始服务器验证当前缓存是否还有效。

用Exires需要指定一个确定的时间,所以需要确保原始服务器和各缓存系统的时间是同步的,不然会引发一些问题。

Cache-Control头

HTTP1.1规范引入了这个新的控制缓存的字段。这个字段是为了解决Expires的一些局限性,是的使用者能有更大的操控缓存的权力。

Cache-Control的有以下这些值,使用时用逗号空格隔开:

  • max-age=[senconds]
  • s-maxage=[seconds]
  • public
  • private
  • no-cache
  • no-store
  • must-revalidate
  • proxy-revalidate

Cache-Control和Exprires同时存在时,前者优先。

Validator和Validation

有验证机制后可以使得资源未更改时获取资源无需再次完整返回资源。

如果没有validator,同时也没有新鲜度信息(Expires或Cache-Control),那么每次请求都会需要将资源完整返回一遍。

当有Last-Modified字段时,如果资源已经比较陈旧了,浏览器就会去向原始浏览器验证当前陈旧缓存的有效性,和没有这个字段的时候相比,浏览器在请求的时候会加上一个If-Modified-Since字段,来告知原始服务器浏览器当前缓存的版本,如果缓存版本还是有效的话,后端就只需要返回一个304状态吗告诉浏览器,而无需把资源完整返回一遍了。

HTTP1.1引入了一个和Last-Modified有类似功能的字段Etag,与前者返回时间不同,Etag返回的是一串能表示当前资源的hash值,后端通过判断hash值是否变化来认定缓存版本是否还有效。对应If-Modified-Since,Etag使用If-None-Match。

总结

HTTP缓存大致的机制就是如此,如果想更深入了解,可以去看看引文2里的延伸阅读。

  • References:
    1. An Explanation of Caching
    2. Caching Tutorial for Web Authors and Webmasters
0 0
原创粉丝点击