缓存的故事

前几天按照Node.js中文社区上的教程,用Node.js搭了一个简单的静态文件服务器,其中有一个功能是提供缓存支持,在实践这一部分的过程当中,我从新学习了缓存的相关知识,在这里做简单的梳理。php

关于缓存的相关介绍,网上有很多文章,这里推荐三篇我认为不错的文章:css

缓存是什么,简单的说,就是访问页面时不须要从新请求浏览器已经缓存的资源(如图片、css、js等),前提是这些位于服务器的资源并无发生变动。因此,如何肯定这些资源没有发生变动、如何控制缓存过时的时间成了必须解决的问题。这些内容在以上三篇文章中都有详细的介绍,我这里仅从四种使用情景来分析浏览器和服务器的交互过程。node

情景一:用户第一次在浏览器中输入网址,或者经过连接访问某个网站web

浏览器(客户端)发出请求,请求网页上的全部资源,一个资源对应一个请求,服务器端收到请求后,向客户端发送200的状态码,表示该资源请求成功,并返回响应头(response header)和数据体。其中,响应头包含了如下几个重要的头信息:浏览器

  • last-modified:该资源(文件)的最后修改时间,为UTC格式
  • Expires:该资源的缓存过时时间,为绝对时间,即过了这个指定时间后缓存失效,为UTC格式
  • Cache-Control:一般经过max-age指定缓存过时时间,为相对时间,表示某次请求成功后多少秒内缓存可用,单位为秒

Cache-Control的出现是由于服务器端的时间可能存在偏差,其优先级高于Expires。浏览器接收到响应后,会记录这些信息,方便以后的缓存控制。缓存

情景二:用户第N次(N大于1)在浏览器中输入网址,或者经过连接访问某个网站服务器

浏览器首先检查待请求的资源的状态,先检查Cache-Control,没有则检查Expires,若是缓存未过时,则浏览器不向服务器端发送请求,直接返回200 from cache,代表是从缓存中获取的资源。也就是说,就算服务器端该资源已经发生变化,只要缓存未过时,就不会从新请求资源,因此刷新的做用就体现出来了。学习

情景三:资源已经缓存,用户刷新页面(按F5)网站

浏览器向服务器发送资源请求,请求头中包含如下两个头信息:.net

  • Cache-Control:其中max-age=0(刷新时置为0),表示本地缓存已过时,要向服务器确认
  • if-modified-since:这是时间等于上一次成功请求该资源后从last-modified获取的时间,为UTC格式

服务器接收到请求,将待请求资源的最后一次修改时间和if-modified-since进行对比。若是前者与后者不相等,则说明文件已经变更,则从新下载该资源,并返回200状态码;若是前者与后者相等,则从本地缓存中获取,并返回304 Not Modified

情景四:资源已经缓存,用户强制刷新页面(按Ctrl + F5)

强制刷新时,请求头中的Cache-Control的值设为no-cache,表示强制发送请求,此外请求头中无If-Modified-Since头信息,这样,不管缓存是否过时,不管服务器端文件是否发生变动,都会强制下载请求的资源,这就是所谓的“强制刷新”。



最后,附上用node.js实现静态文件服务器的教程:

用NodeJS打造你的静态文件服务器

相关文章
相关标签/搜索