Express中间件

原文地址: http://www.cnblogs.com/hbzyin/p/7381530.html

引入

伴随着nodejs流行,往日被无数后端程序员所不屑诟病的脚本语言Javascript的重要性与日俱增,2017年IBM一项调查数据显示,目前为止这个小巧灵活的语言已经跃升至用户量第一的编程语言;

Express作为nodejs官方首推的Web框架,也发挥出了巨大的潜力,Express团队现在正在开发更加小巧灵活的下一代nodejs框架KOA,相信也会让很多开发者眼前一亮。
为什么中间件这么重要,试想以下场景,如何解决:
1.开发过程中在处理http请求过程中,我们需要对请求对象、响应对象做某些特殊预处理工作,最后才会将处理的结果作为响应发送给请求;
2.请求处理http请求时,需要对所有的请求进行预先处理,比如检查请求的头信息是否存在必须的字段,检验请求的合法性,并做响应拦截过滤;

基本上有两种方案可以解决以上问题:

  • 在每处请求响应出都定义中间处理函数,最终做出响应;
  • 定义全局的中间处理函数,在各处请求响应中进行引用;

是的,express中间件要解决的问题正是我们以上的需求。

简介

Express是一个路由中间件Web框架,其自身只具有最低程度的功能,即:一系列中间件函数的调用。

express 中间件函数的特点及作用

  1. 特点:中间件函数能够访问请求对象(req)、响应对象(res)、下一个中间件函数(next);中间件默认按载入顺序依次执行,直到请求响应循环结束;
  2. 作用:①对请求对象进行处理;②对响应对象进行处理;③执行任意自定义功能;④调用下一个中间件;⑤结束请求响应循环;
  3. 中间件种类:①应用层中间件;②路由层中间件;③错误处理中间件;④内置中间件;⑤第三方中间件

1.中间件示例

先来看一个最最简单的Hello world Express应用程序示例:

var express=require('express');
var app=express();
app.get('/',function(req,res){
  res.send('Hello world!')
  })
app.listen(3000);

现在我们用一个最简单的中间件来实现:在GET 方法请求根路径/时,先在服务窗口打印出'Response with middleware is working ok.',再响应输出’Hello World!’

var express=require('express');
var app=express();
app.get('/',function(req,res,next){
  console.log('Response with middleware is working ok.');
  next();
  },function(req,res){
  res.send('Hello world!')
  })
app.listen(3000);

2. 中间件使用方法

  1. 在各个响应请求处理处单独定义中间处理函数,如上面的例子;
  2. 采用express.use()载入中间件函数,从载入位置开始,后续执行的请求响应循环都会执行该处的中间件函数;

如前文中场景2,在所有请求响应前在服务窗口打印出请求的log信息,如当前时间;

var express=require('express');
var app=express();
var logTime=function(req,res,next){
  console.log(Date.now());
  next();
};
app.use(logTime);
app.get('/',function(req,res){
  res.send('This is response from server.')
  })
app.listen(3000);

3. 中间件种类

express中应用层中间件即最常用的中间件,如上Hello world示例;路由中间件、第三方中间件与应用层中间件基本一致,不同之处在于,第三方中间件载入时需要提前引入,此时与引入的应用层中间件一致;这里对错误处理、内置中间件稍作说明;

  1. 错误处理中间件
  • 错误处理中间件的定义与其他中间件函数基本相同,差别在于错误处理中间件函数有4个参数,(err,req,res,next)
  • 错误处理中间件通常在所有其他中间件之后进行载入;
  • Express 内附有一个缺省的错误处理中间件(处理程序),其位置位于中间函数集的末尾
    错误处理中间件如下:
app.use(function(err,req,res,next){
  console.log(err.stack);
  res.status(500).send('Something broke!')
  })
  1. 内置中间件
    Express内置的中间件函数都已单独模块形式提供;目前仅依赖express.static(root,[options])负责提供Express应用程序的静态资源;
    先来看一个options对象的配置:
var options={
  dotfiles:'ignore',
  etag:false,
  extensions:['htm','html'],
  index:false,
  maxAge:'1d',
  redirect:false,
  setHeaders:function(res,path,stst){
    res.set('x-timestamp',Date.now())
  }
}
app.use(express.static('public',options))

options对象具有以下属性:

序号 属性名称 类型 默认值 作用
1 dotfiles String 'ignore' 是否对外输出以.开头的文件
2 etag Boolean true 启用或开启etag
3 extensions Array [] 用于设置后备文件扩展名
4 index 混合 ‘index.html’ 发送文件索引目录
5 lastModified Boolean true 将Last-Modified的头设置为操作系统对应文件上次修改的有效值
6 maxAge Number 0 设置Cache-Control头的max-age属性(ms)
7 redirect Boolean true 当前路径是目录是中定向到结尾的/
8 setHeaders function(){} 设置随文件一起提供的HTTP头信息

每个应用程序,可以对应多个静态目录,如:

app.use(express.static('public'));
app.use(express.static('share'));
app.use(express.static('files'));

4. 其他:

  • 中间件会按照载入的位置及顺序进行顺序执行,亦即中间件的载入位置顺序都会影响程序的处理结果;
  • 中间件默认会一次执行,直到请求响应循环结束,亦即处理程序在遇到响应结束/响应发送的位置结束,而不会继续后续的中间件函数;
  • 中间件必须通过next()来调用后续中间件,否则响应将处于挂起状态;
  • 中间件可通过next('route')跳过当前路由 中间件堆栈中剩余的中间件函数,将控制权传递给下一个路由;(该方法仅在使用app.METHOD()、router.METHOD()函数载入的中间件函数有效);
  • express中定义了9种响应方法,来结束请求响应循环,具体如下:
序号 方法名 说明
1 res.send() 发送各种类型的响应
2 res.senFile() 发送八位元流形式的文件
3 res.sendStatus() 设置响应状态码,并以响应主体形式发送其字符串表示
4 res.json() 发送json响应
5 res.jsonp() 在jsonp的支持下,发送json响应
6 res.render() 呈现视图模板
7 res.redirect() 重定向请求
8 res.download() 提示将要下载文件
9 res.end() 结束响应进程

--END

原文地址:https://www.cnblogs.com/hbzyin/p/7381530.html