前面我们讲解了 express 中路由和模板引擎 ejs 的用法,但 express 的精髓并不在此,在于中间件的设计理念。
## 3.4.1 中间件与 next
express 中的中间件(middleware)就是用来处理请求的,当一个中间件处理完,可以通过调用 `next()` 传递给下一个中间件,如果没有调用 `next()`,则请求不会往下传递,如内置的 `res.render` 其实就是渲染完 html 直接返回给客户端,没有调用 `next()`,从而没有传递给下一个中间件。看个小例子,修改 index.js 如下:
**index.js**
```
var express = require('express');
var app = express();
app.use(function(req, res, next) {
console.log('1');
next();
});
app.use(function(req, res, next) {
console.log('2');
res.status(200).end();
});
app.listen(3000);
```
此时访问 `localhost:3000`,终端会输出:
```
1
2
```
通过 `app.use` 加载中间件,在中间件中通过 next 将请求传递到下一个中间件,next 可接受一个参数接收错误信息,如果使用了 `next(error)`,则会返回错误而不会传递到下一个中间件,修改 index.js 如下:
**index.js**
```
var express = require('express');
var app = express();
app.use(function(req, res, next) {
console.log('1');
next(new Error('haha'));
});
app.use(function(req, res, next) {
console.log('2');
res.status(200).end();
});
app.listen(3000);
```
此时访问 `localhost:3000`,终端会输出错误信息:
![](https://box.kancloud.cn/aea60c15dcbc30cce9d89e2ecb576439_941x231.png)
浏览器会显示:
![](https://box.kancloud.cn/8b70011c96f678cebdc1548c542ba359_943x194.png)
> 小提示:`app.use` 有非常灵活的使用方式,详情见 [官方文档](http://expressjs.com/en/4x/api.html#app.use)。
express 有成百上千的第三方中间件,在开发过程中我们首先应该去 npm 上寻找是否有类似实现的中间件,尽量避免造轮子,节省开发时间。下面给出几个常用的搜索 npm 模块的网站:
1. [http://npmjs.com](http://npmjs.com)(npm 官网)
2. [http://node-modules.com](http://node-modules.com)
3. [https://npms.io](https://npms.io)
4. [https://nodejsmodules.org](https://nodejsmodules.org)
> 小提示:express@4 之前的版本基于 connect 这个模块实现的中间件的架构,express@4 及以上的版本则移除了对 connect 的依赖自己实现了,理论上基于 connect 的中间件(通常以 `connect-` 开头,如 `connect-mongo`)仍可结合 express 使用。
> 注意:中间件的加载顺序很重要!比如:通常把日志中间件放到比较靠前的位置,后面将会介绍的 `connect-flash` 中间件是基于 session 的,所以需要在 `express-session` 后加载。
## 3.4.2 错误处理
上面的例子中,应用程序为我们自动返回了错误栈信息(express 内置了一个默认的错误处理器),假如我们想手动控制返回的错误内容,则需要加载一个自定义错误处理的中间件,修改 index.js 如下:
**index.js**
```
var express = require('express');
var app = express();
app.use(function(req, res, next) {
console.log('1');
next(new Error('haha'));
});
app.use(function(req, res, next) {
console.log('2');
res.status(200).end();
});
//错误处理
app.use(function(err, req, res, next) {
console.error(err.stack);
res.status(500).send('Something broke!');
});
app.listen(3000);
```
此时访问 `localhost:3000`,浏览器会显示 `Something broke!`。
> 小提示:关于 express 的错误处理,详情见 [官方文档](http://expressjs.com/en/guide/error-handling.html)。
- 使用 Express + MongoDB 搭建多人博客
- 1.1 Node.js 的安装与使用
- 1.2 MongoDB 的安装与使用
- 2.1 require
- 2.2 exports 和 module.exports
- 2.3 Promise
- 2.4 环境变量
- 2.5 package.json
- 2.6 npm 使用注意事项
- 3.1 初始化一个 Express 项目
- 3.2 路由
- 3.3 模板引擎
- 3.4 Express 浅析
- 4.1 开发环境
- 4.2 准备工作
- 4.3 配置文件
- 4.4 功能设计
- 4.5 页面设计
- 4.6 连接数据库
- 4.7 注册
- 4.8 登出与登录
- 4.9 文章
- 4.10 留言
- 4.11 404 页面
- 4.12 错误页面
- 4.13 日志
- 4.14 测试
- 4.15 部署