nodejs之express中间件

前言

目前最主流的nodejs框架应该就是express和koa了,两者都是同一个团队开发的。koa更新一点,而且一些设计思想要比express更成熟,不过仍有大量的项目在使用express。
做者对于express框架的定义为“==基于 Node.js 平台,快速、开放、极简的 Web 开发框架==”。说明express框架自己并无太多功能,而其大多功能都是经过中间件实现的。因而可知中间件在express中的重要性。html

何为中间件?

当客户端的请求到达服务器后,nodejs会为请求建立一个请求对象叫request,该对象上包含了请求的信息以及客户端传来的数据。同时也会建立一个响应对象-response,响应对象主要负责将服务器处理的结果返回给客户端。那么在服务端响应结果以前就能够插入多个中间件。中间件就能够理解成一个对请求进行过滤和预处理的东西,但他不会直接对客户端进行响应,而是将处理以后的结果向下传递,这也就是为何能够插入多个中间件了。node

在早先的express版本中,中间件使用了Connect中间件框架,3.0版本的express就移除了除‘express.static’外的所有内置中间件,而在4.0版本的express框架中已经不在依赖Connect。能够说新版的express是一个独立的路由和中间件的web框架。web

使用中间件

除了使用express.static外的其余中间件都须要安装,
npm i <MiddleWare-name> -D
而后在应用中引入中间件:const mod = require('MiddleWare-name');
按照文档描述使用中间件:server.use(……);express

下面来看看中间件具体的使用npm

express.static
先来看惟一一个express内置的中间件——static,static中间件是用来处理文件请求的。数组

const express = require('express');

let server = express();
server.listen(8080);

server.get('/reg', (req, res, next) => {
  res.send('ok');
});

server.use(express.static('./static/'));

经过server.use使用中间件,在express.static中传入文件路径,在客户端发起文件请求时,服务器就会在该路径下查找对应文件。
注意一点,该中间件通常放到最后使用,由于若是放在路由以前,那么一旦有与接口名字相同的文件请求时,就会先请求文件,这样就不会走到路由中去了。浏览器

body-parser
body-parser是帮助解析post数据的中间件,首先须要安装中间件
npm i body-parser -D服务器

const express = require('express');
// 1
const body = require('body-parser');

let server = express();
server.listen(8080);

// 2
server.use(body.urlencoded({
  extended: false // 是否开启扩展模式
}));

// 3
server.post('/reg', {req, res} => {
    let { name, pwd } = req.body;
    res.send('ok');
})
  1. 引入中间件;
  2. 这个中间件的使用就要放到路由以前了,由于它是对请求数据的处理;
  3. 使用了该中间件后,请求对象req上就会多出一个body属性,body属性装载的就是请求的数据。经过body就能够拿到请求的参数;

到这里咱们演示两个比较重要和经常使用的第三方中间件,掌握如何使用中中间件以后(就是调用"server.use(...)" )。其余第三方中间件的使用就大同小异了,至于为何express.static中间件是调用express.static(),而body-parser中间件是调用body.urlencoded(),这就是做者要求的了,具体调用方式和配置参数还要参考文档。框架

next方法

express的中间件模式与koa的是不同的,koa是洋葱型,express是直线型。
在express中间件函数中有三个参数,分别是req、res、next。前两个参数前面有提到过。而最后一个参数next是一个方法,由于一个应用中可使用多个中间件,而要想运行下一个中间件,那么上一个中间件必须运行next()。koa

其实express中间件的原理很简单,express在内部维护一个数组,这个数组盛放的是在发出响应以前要执行的全部函数,也能够理解为中间件数组,每一次use之后,传进来的中间件就会放到到数组中,执行完毕后调用next方法执行数组的下一项,若是没有下一项,那么调用就会终止。

你们可能会有疑问,为何上面使用的两个中间件并无看到调用next(),可是程序也能够一直向下走呀?那是由于上面的两个中间件是属于内置和第三方中间件,在其封装好的代码中做者已经将next的调用写了进去,中间件执行完已经调用了next(),只不过咱们做为使用者看不到而已。下面经过一个咱们本身写的中间件实现的简易body-parser功能更清楚的了解next的使用。

手写中间件,实现简版body-parser

当咱们能够熟练的使用第三方中间件的时候就要考虑如何本身写一个中间件。其实实现起来并不难,下面就是一个简版的body-parser中间件的实现过程。
1.首先在项目中建立一个libs目录,在目录中建立一个body-parser.js文件。注意这里咱们再也不须要安装body-parser。

const querystring = require('querystring');

module.exports = {
  // 为了模拟第三方中间件的调用方式,这里也使用urlencoded包裹
  urlencoded() {
    return (req, res, next) => {
      let arr = [];
      req.on('data', buffer => {
        arr.push(buffer);
      });
      req.on('end', () => {
        let post = querystring.parse(Buffer.concat(arr).toString());
        // 讲解析好的数据放到req对象的body属性上
        req.body = post;
        // 调用next方法结束当前中间件的调用,执行后续的操做
        next();
      });
    };
  }
};

2.而后在server.js中引入咱们写的中间件,这里的body-parser就不是第三方的body-parser了,而是咱们本身写的body-parser。

const express = require('express');
const body = require('./libs/body-parser');

let server = express();
server.listen(8080);

server.use(body.urlencoded());

server.post('/reg', (req, res, next) => {
  console.log(req.body);
  res.send('ok');
});

server.use(express.static('./'));

3.而后在项目根目录建立user.html文件,内部实现一个简单的form表单

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <form class="" action="http://localhost:8080/reg" method="post">
      <input type="text" name="user" value="">
      <input type="password" name="pass" value="">
      <input type="submit" name="" value="注册">
    </form>
  </body>
</html>

4.最后启动服务
node server.js
在浏览器中访问 http://localhost:8080/user.html
填写表单,点击提交按钮,查看在命令行中查看。
在这里插入图片描述
表单提交的数据成功被解析而且打印到命令行中了。

这样一个最简版的body-parser中间件就实现了,其实内部就是对post请求数据的解析处理。固然第三方的中间件里面的逻辑处理要比咱们实现的复杂不少,不过原理都是同样的。

底层原理(Connect框架)

其实express中间件的实现依赖了Connect中间件框架,也就是说早先版本的express框架的中间件彻底是由另外一个独立的框架Connect实现的,Connect也是express框架的做者编写的。在express3.0版本中是包含了Connect框架的。而4.0版本中已经移除了对Connect的依赖,在内部实现了Connect接口。

Connect框架的源码写的仍是很是经典的,next的设计尤其巧妙,简单易懂。本篇只是对中间件的使用的介绍,而且还告诉你们如何本身写中间件。若是对Connect的底层实现有兴趣,请看下篇文章。《nodejs之中间件框架Connect源码浅谈》

相关文章
相关标签/搜索