Skip to content
本页目录

缓存机制与应用

HTTP请求缓存可以提高Web应用程序的性能和响应速度,并且减少网络流量。常见的HTTP请求缓存有以下几种

  1. 浏览器缓存:浏览器会将已经请求过的资源(如HTML、CSS、JavaScript、图片等)保存到本地的缓存中,当下次需要访问同一资源时直接从缓存中读取,避免了重新发送请求和下载资源的开销。

  2. 代理服务器缓存:代理服务器是介于客户端和服务器之间的一台服务器,它可以缓存Web页面和其他网络资源,从而降低了响应时间和带宽需求。

  3. CDN缓存:CDN(内容分发网络)是一种分布式服务器系统,它通过在全球各个节点上缓存网站内容,以加速用户获取数据的速度。当用户请求某个资源时,CDN会根据用户的位置和就近原则选择最合适的边缘节点来提供资源,从而实现快速访问。

  4. 应用程序缓存:应用程序也可以创建自己的缓存,以减少对数据库和其他后端服务的请求。例如,在PHP应用程序中,可以使用APC缓存或Memcached缓存来存储查询结果、对象、文件等。

  5. 数据库查询缓存:MySQL等数据库管理系统可以缓存查询结果,以提高查询效率。当查询请求到来时,数据库会首先检查是否存在缓存结果,如果存在则直接返回缓存结果而不必执行实际查询。

浏览器缓存

浏览器是常见的Web客户端,它可以在本地缓存Web页面和其他网络资源,以提高访问速度和响应性能。以下是浏览器中常见的缓存类型

  1. HTTP缓存:浏览器会将已经请求过的资源(如HTML、CSS、JavaScript、图片等)保存到本地的HTTP缓存中,当下次需要访问同一资源时直接从缓存中读取。

  2. DNS缓存:DNS缓存可以加速域名解析,减少DNS查询的时间和网络流量。浏览器会将最近访问的域名及其IP地址保存到本地缓存中,以便下次快速访问。

  3. 数据库缓存:浏览器支持使用Web SQL Database或IndexedDB等技术创建本地数据库,用于存储应用程序数据和缓存数据。这些数据库可以通过JavaScript进行访问和操作,并且具有较好的容错性和离线功能。

  4. 应用程序缓存:浏览器允许Web应用程序创建自己的缓存,以减少对网络资源的请求和响应时间。例如,在HTML5中可以使用Application Cache来存储Web应用的静态文件,包括HTML、CSS、JavaScript等。

  5. Cookie缓存:Cookie是一种小型的文本文件,它可以存储在浏览器中并随着HTTP请求一起发送到服务器。浏览器会将Cookie保存到本地缓存中,并在下次访问同一站点时自动发送。

强缓存和协商缓存

  1. 浏览器每次发起请求前,都会先在浏览器缓存中查找该请求的结果和缓存标识。如果没有缓存或缓存失效,才会去进一步请求服务器。

  2. 浏览器每次拿到返回的请求结果都把结果和缓存标识存入浏览器缓存中,以供之后直接使用

浏览器主要有两种缓存策略:强缓存 和 协商缓存

强缓存是通过在服务器返回响应头中添加ExpiresCache-Control字段来实现的。当客户端请求某个资源时,如果它在强缓存有效期内,则直接从本地缓存中读取,而不必发送请求到服务器端。这种缓存方式适用于静态资源的缓存,如CSS、JavaScript和图片等。

  • Expires是HTTP/1.0协议中定义的字段,它通过指定一个绝对过期时间来控制客户端缓存的有效期。例如,Expires: Thu, 01 Dec 2022 08:00:00 GMT表示该资源在2022年12月1日8点过期,客户端在此日期之前再次请求该资源时可以直接从本地缓存中读取,而不必发送请求到服务器。

  • Cache-Control是HTTP/1.1协议中定义的字段,它可以更加灵活地控制缓存的行为。Cache-Control字段有多个可选项,包括max-age、no-cache、no-store、public、private等。其中,max-age表示资源的最长缓存时间(单位为秒),例如Cache-Control: max-age=3600表示该资源可以缓存一小时。no-cache和no-store都表示禁止缓存该资源,但前者仍需要向服务器验证缓存是否过期,后者则完全忽略缓存。

协商缓存则是通过在服务器返回响应头中添加ETagLast-Modified字段来实现的。当客户端请求某个资源时,如果它在协商缓存有效期内,则会向服务器发送一个条件请求,并带上If-None-MatchIf-Modified-Since字段,以确认是否需要更新缓存。这种缓存方式适用于动态资源的缓存,如HTML页面等。

  • Last-Modified 标识本地文件最后修改时间。发送请求时,会将当前的 Last-Modified 值作为 If-Modified-Since 字段的内容,放在请求头中发送给服务器,去询问服务器在这个时间后资源是否有更新。有更新的话服务端就返回新的资源,没有的话返回 304 状态码。

  • ETag 类似于文件指纹。客户端请求时会将当前的 ETag 作为 If-None-Match 字段的内容,并放在请求头中发送给服务器。服务器接收到 If-None-Match 后会跟服务器上该资源的 ETag 进行对比。如果有变动的话,就把新的资源返回,没有的话返回 304 状态码。

强缓存和协商缓存都属于HTTP请求缓存,但它们是两种不同的缓存机制,适用于不同类型的资源。当客户端请求某个资源时,浏览器会首先检查强缓存是否命中,若未命中则再检查协商缓存是否命中,最后才发送请求到服务器获取新的资源。

浏览器的缓存过程

  1. 浏览器第一次加载资源时,服务器返回状态码 200,浏览器把资源文件从服务器上请求下载下来,并把 response header 及该请求的返回时间一起缓存下来。

  2. 下一次加载资源时,先比较当前时间和上一次返回 200 时的时间差,如果没超过 Cache-Controlmax-age,则缓存没有过期,命中强缓存,不发请求直接读取本地缓存。如果浏览器不支持 HTTP 1.1,则用 expires 判断是否过期。如果时间过期,浏览器向服务器发送 header 带有 If-None-MatchIf-Modified-Since 的请求。

  3. 服务器收到请求后,有优先根据 ETag 的值判断被请求的文件有没有修改,没有修改则命中协商缓存,返回 304。反之,直接返回新资源,带上新的 ETag 值并返回 200

  4. 如果服务器收到的请求没有 ETag 值,则将 If-Modified-Since 和被请求文件的最后修改时间做比对,相同则命中协商缓存;反之返回新的 Last-Modified 和文件,并返回 200