1. 中间件概念
http://expressjs.com/en/guide/using-middleware.html
中间件的本质就是一个请求处理方法,我们把用户从请求到响应的整个过程分发到多个中间件中去处理,提高代码的灵活性,动态可扩展性
- 同一个请求所经过的中间件都是同一个请求对象和响应对象
没有中间件时:
- 解析表单 get 请求体
- 解析表单 post 请求体
- 解析 Cookie
- 处理 Session
- 使用模板引擎
var server = http.createServer(function (req, res) {
// 默认req是没有这些的,用了express有些可以直接拿到,有些配插件就能拿到
// console.log(req.query)
// console.log(req.body) 配插件
// console.log(req.cookies)
// console.log(req.session)
var urlObj = url.parse(req.url, true) // 解析请求地址中的 get 参数
req.query = urlObj.query
req.body = { foo: 'bar' } // 解析请求地址中的 post 参数
req.cookies = { isLogin: true } // 解析 Cookie
req.session = {} // 配置 Session
res.render = function () {} // 配置模板引擎
if (req.url === 'xxx') {
// 处理 query、body、cookies、session、render 这些API 成员
} else if (url === 'xx') {
// 处理
}
// 上面的过程都是了为了在后面做具体业务操作处理的时候更方便
})
使用中间件:
文件middlewares
:下有cookie.js
,post-body.js
,query.js
,session.js
post-body.js
:
module.exports = function (req, res) {
req.body = {}
}
query.js
module.exports = function (req) {
req.query = {}
}
var cookie = require('./middlewares/cookie')
var postBody = require('./middlewares/post-body')
var query = require('./middlewares/query')
var session = require('./middlewares/session')
var server = http.createServer(function (req, res) {
query(req, res) // 解析请求地址中的 get 参数
postBody(req, res) // 解析请求地址中的 post 参数
cookie(req, res) // 解析 Cookie
session(req, res) // 配置 Session
res.render = function () {} // 配置模板引擎
if (req.url === 'xxx') {
// 处理 query、body、cookies、session、render 这些API 成员
} else if (url === 'xx') {
// 处理
}
// 上面的过程都是了为了在后面做具体业务操作处理的时候更方便
})
2. Express 中的中间件
2.1 中间件
-
中间件:处理请求的,本质就是个函数
-
中间件本身是一个方法,该方法接收三个参数:
-
Request 请求对象
-
Response 响应对象
-
next 下一个中间件
-
2.2 应用程序级别中间件
-
万能匹配(不关心请求路径和请求方法的中间件,也就是说任何请求都会进入这个中间件)
app.use(function (req, res, next) { console.log(1) next() })
-
以 /xxx 开头的路径中间件
app.use('/a', function (req, res, next) { console.log('Time:', Date.now()) next() })
2.3 路由级别中间件
严格匹配请求方法和请求路径的中间件app.get
, app.post
路由中间件 | 语法 |
---|---|
get | app.get('/', function (req, res) { res.send('Hello World!') } |
post | app.post('/', function (req, res) { res.send('Got a POST request') }) |
put | app.put('/user', function (req, res) { res.send('Got a PUT request at /user') }) |
delete | app.delete('/user', function (req, res) { res.send('Got a DELETE request at /user') }) |
- 中间件匹配步骤:
-
当请求进来,会从第一个中间件开始进行匹配
-
如果匹配,则进来
-
如果请求进入中间件之后,没有调用 next 则代码会 停在当前中间件
-
如果调用了 next 则继续向后找到第一个匹配的中间件
-
如果不匹配,则继续判断匹配下一个中间件
-
-
当一个请求进入一个中间件之后,如果不调用 next 则会停留在当前中间件
-
所以 next 是一个方法,用来调用下一个中间件的
-
调用 next 方法也是要匹配的(不是调用紧挨着的那个)
-
如果没有能匹配的中间件,则 Express 会默认输出:Cannot GET 路径
2.4 错误处理中间件
app.use(function(err,req,res,next){
console.log(err.stack)
res.status(500).send('Something broke!')
})
04-中间件.js
app.get('/', function (req, res, next) {
fs.readFile('.d/sa./d.sa/.dsa', function (err, data) {
if (err) {
// return res.status(500).send('Server Error')
// 当调用 next 的时候,如果传递了参数,则直接往后找到带有 四个参数的应用程序级别中间件
// 当发生错误的时候,我们可以调用 next 传递错误对象,然后就会被全局错误处理中间件匹配到并处理之
next(err)
}
})
})
app.use(function (req, res, next) {
res.send('404')
})
// 配置错误处理中间件
app.use(function (err, req, res, next) {
res.status(500).send(err.message)
})
2.5 内置中间件
内置中间件 | 功能 |
---|---|
express.static | 提供静态资源,例如 HTML 文件、图像等 |
express.json | 使用 JSON 有效负载解析传入请求。注意:可用于 Express 4.16.0+ |
express.urlencoded | 解析带有 URL 编码负载的传入请求。注意:可用于 Express 4.16.0+ |
2.5 第三方中间件
第三方中间件 | 功能 | 网址 |
---|---|---|
body-parse | 解析 HTTP 请求正文 | http://www.expressjs.com.cn/en/resources/middleware/body-parser.html |
compression | 压缩 HTTP 响应 | http://www.expressjs.com.cn/en/resources/middleware/compression.html |
cookie-parser | 解析 cookie 标头并填充req.cookies | http://www.expressjs.com.cn/en/resources/middleware/cookie-parser.html |
morgan | HTTP 请求记录器 | http://www.expressjs.com.cn/en/resources/middleware/morgan.html |
response-time | 记录 HTTP 响应时间 | http://www.expressjs.com.cn/en/resources/middleware/response-time.html |
server-static | 提供静态文件 | http://www.expressjs.com.cn/en/resources/middleware/serve-static.html |
session | 建立基于服务器的会话(仅限开发) | http://www.expressjs.com.cn/en/resources/middleware/session.html |