NodeJS中的客户端缓存、浏览器缓存、304缓存和OnceIO的缓存控制


发布者 ourjs  发布时间 1478305458502
关键字 JS学习  Node.JS 

OnceIOOnceDoc企业私有内容(网盘)管理系统的底层Web框架,它可以实现模板文件、静态文件的全缓存,运行起来完全不需要I/O操作,并且支持客户端缓存优化,GZIP压缩等(只压缩一次),拥有非常好的性能,为您节约服务器成本。它的模块化功能,可以让你的Web进行分布式存储,在一个扩展包里即可包含前端、后端和数据库定义,只需通过添加/删除目录的方式就可实现功能删减,实现真正的模块化扩展。目前OnceIO已经开源,这里是介绍如何使用的一系列文章。

 

客户端缓存

缓存定义

这里讨论的缓存是指 web 缓存:一个 web 资源(如 html 页面、图片、文件等)在服务器和客户端(浏览器)之间的副本。缓存会根据进来的请求保存请求输出的内容的副本;然后,如果下一个请求是相同的 URL,且网页在这段时间内没有更新,浏览器就不会再次下载网页,而是直接使用本地缓存的网页副本。

缓存的作用主要有:

  • 节约带宽。
  • 减少延迟。
  • 降低服务器压力。

客户端(浏览器)的缓存机制

所有的缓存都有一套规则来帮助它们决定什么情况下使用缓存中的副本,什么情况下向源服务器再次发送请求。这些规则有的在协议(如 HTTP 协议 1.0 和 1.1)中有定义,有的则是由缓存的管理员(如 DBA、浏览器的用户、代理服务器管理员或者应用开发者)设置。

对于浏览器端的缓存,这些规则是在 HTTP 协议头和 html 页面的 meta 标签中定义的。它们从新鲜度和校验值两个维度来决定浏览器是否可以直接使用缓存中的副本。

新鲜度(过期机制):也就是缓存副本有效期。一个缓存副本必须满足以下条件,浏览器才会认为它是有效的:

  1. 含有完整的过期时间控制头信息(HTTP协议报头),并且仍在有效期内;
  2. 浏览器已经使用过这个缓存副本,并且在一个会话中已经检查过新鲜度;

满足以上两个情况的一种,浏览器会直接从缓存中获取副本并渲染。

校验值(验证机制):服务器返回资源的时候有时在控制头信息带上这个资源的实体标签 ETag(Entity Tag),它可以用来作为浏览器再次请求过程的校验标识。如过发现校验标识不匹配,说明资源已经被修改或过期,浏览器需求重新获取资源内容。

常用的与缓存有关的 HTTP 消息报头
消息报头类型作用规则
Status Code200 OK普通表明服务器成功返回网页不适用
 304 Not Modified普通表明当前资源的内容(自上次访问以来或根据请求的条件)没有修改过,服务器不返回网页内容不适用
Cache-Controlmax-age=315360000响应指明缓冲副本的有效时长,单位为秒新鲜度
ExpiresThu, 31 Dec 2037 23:55:55 GMT响应告诉浏览器在过期时间前可以使用副本新鲜度
Last-ModifiedSun, 23 Oct 2016 06:36:08 GMT响应告诉浏览器当前资源的最近一次修改时间新鲜度
If-Modified-SinceSun, 23 Oct 2016 06:36:08 GMT请求如果浏览器第一次请求时响应中 Last-Modified 非空,第二次请求同一资源时,会把它作为该项的值发给服务器新鲜度
ETag978534响应告诉浏览器当前资源在服务器的唯一标识符(生成规则由服务器决定)校验值
If-None-Match978534请求如果浏览器第一次请求时响应中 ETag 非空,第二次请求同一资源时,会把它作为该项的值发给服务器校验值

以访问网站 http://oncedoc.com/ 为例,网站的 shader.css 文件的 HTTP 头信息为:

shadercss  HTTP

 
客户端缓存生效的常见流程

服务器收到请求时,在 200 OK 响应中回送该资源的 Last-Modified 和 ETag,客户端将该资源保存在缓存中,并记录这两个属性。当客户端再次发送相同的请求时,会在请求中携带 If-Modified-Since 和 If-None-Match 两个消息报头。两个报头的值分别是上次请求收到的响应中 Last-Modified 和 ETag 的值。服务器通过这两个头判断本地资源未发生变化,客户端不需要重新下载,返回 304 响应。以访问 oncedoc.com 为例,客户端缓存生效流程如下:

用户操作行为与缓存

用户在使用浏览器的时的各种操作,如输入地址后回车,按F5刷新等,对缓存有可能会造成影响。

用户操作Expires/Cache-ControllLast-Modified/ETag
地址栏回车有效有效
页面链接跳转有效有效
新开窗口有效有效
前进后退有效有效
F5 刷新无效有效
Ctrl+F5 强制刷新无效无效

当用户在按 F5 进行刷新时,浏览器会忽略 Expires/Cache-Control 的设置,再次向服务器发送请求,而 Last-Modified/Etag 仍然是有效的,服务器会根据情况判断返回 304 还是 200 ;而当用户使用 Ctrl+F5 进行强制刷新的时候,所有的缓存机制都将失效,;浏览器将重新从服务器下载资源并返回 200。

 

 

在服务器端设置客户端缓存机制

浏览器端缓存

运行服务器,访问 localhost:8054/img,打开浏览器开发者工具中的 Network 栏,地址栏回车,Network 显示:

 rescache0  Network

此时浏览器直接从本地获取图片资源,浏览器和服务器之间并没有进行I/O操作。浏览器没有问服务器端是否有更新,而直接从本地缓存中获取资源。

res.cache(0)

有时侯,我们可能需要禁用浏览器端的缓存机制,然后让浏览器发送一次请求询问是否有更新(比如ajax操作)。可以用添加一个 cache-control的header: res.cache(0),即0秒后立即失效(不缓存),示例代码如下:

app.use(function(req, res) {
  res.cache(0)
  req.filter.next()
})

app.get('/img', function(req, res) {
  res.render('img.html')
}) 

此时浏览器与服务器之间会进行一次 I/O,如果本地缓文件的修改时间(IF-Modify-since)与服务器端的一致,即没有修改,则OnceIO会发出 304 响应(如图所示),告诉浏览器从本地缓存中获取资源;如果服务器端文件有更新,OnceIO则会发出 200 响应,并将更新资源重新发给浏览器。

 rescache0  Network

此时服务器端通过304告诉浏览器从本地缓存中获取资源。

通过res.cache接口,您可以根据您应用的Release周期(周、月)来设置资源文件缓存的最大缓存时间,来优化您的应用,比如一周后过期:

res.cache(7*24*3600)

下一节我们将介绍OnceIO的服务器端的模板和静态文件缓存和gzip压缩机制,和其一次读取,永久使用的实现原理。

 

 

OnceIO项目: https://github.com/OnceDoc/onceio









 热门文章 - 分享最多
  1. 阿里任性Hr开除月饼极客:这样冰冷的公司没什么值得我留恋
  2. GitHub2016报告AngularJS流行度下降,JavaScript活跃度为Java两倍
  3. 在 2016 年学 JavaScript 是一种什么样的体验?
  4. 2016年收入最高的5个编程语言,JavaScript最流行,Java和C没在前5
  5. 传言GITHUB正在寻求第二轮融资,或面临估值下降、清算或被微软收购
  6. JavaScript函数式编程(一、二、三)
  7. Java 之父求职被嫌年纪大,硅谷公司现在喜欢“小鲜肉”,不爱“老古董”
  8. NodeJS中的Middleware是什么?在OnceIO中创建和使用中间件
  9. OnceIO(Node.JS)中的模板引擎是什么及MVC设计模式的使用与实现
  10. 用OnceIO(NodeJS)搭建简单的web服务器

 相关阅读
  1. OnceIO(Node.JS)的路由(Routing)、路由方法和路由变量
  2. Node.JS的表单提交及OnceIO中接受GET/POST数据的三种方法
  3. OnceIO(Node.JS)中安装、使用和更换doT、EJS、pug等模板引擎
  4. OnceIO(Node.JS)中的模板引擎是什么及MVC设计模式的使用与实现
  5. NodeJS中的Middleware是什么?在OnceIO中创建和使用中间件
  6. 用OnceIO(NodeJS)搭建简单的web服务器
  7. JavaScript函数式编程(一、二、三)
  8. JavaScript在物联网中的应用
  9. 如何编写 jQuery 插件
  10. NodeJS中npm3相对于npm2模块依赖目录层欠的改进

  开源的 OurJS
OurJS开源博客已经迁移到 OnceOA 平台。

  关注我们
扫一扫即可关注我们:
OnceJS

OnceOA