概述
Express_是一种保持最低程度规模的灵活Node.js Web 应用程序_框架,为Web 和移动应用程序提供一组强大的功能。是对于原生HTTP模块的进一步封装
使用
安装
npm install express
Request和Response对象
首先是 Request 请求对象,通常我们习惯用 req
变量来表示。下面列举一些 req
上比较重要的成员:
-
req.body
:客户端请求体的数据,可能是表单或 JSON 数据 -
req.params
:请求 URI 中的路径参数 -
req.query
:请求 URI 中的查询参数 -
req.cookies
:客户端的 cookies
然后是 Response 响应对象,通常用 res
变量来表示,可以执行一系列响应操作
// 发送一串 HTML 代码
res.send('HTML String');
// 发送一个文件
res.sendFile('file.zip');
// 渲染一个模板引擎并发送
res.render('index');
复制代码
路由机制
客户端(包括 Web 前端、移动端等等)向服务器发起请求时包括两个元素:路径(URI)以及 HTTP 请求方法(包括 GET、POST 等等)。路径和请求方法合起来一般被称为 API 端点(Endpoint)。而服务器根据客户端访问的端点选择相应处理逻辑的机制就叫做路由。
定义路由的方式
app.METHOD(PATH, HANDLER)
app
就是一个express
服务器对象METHOD
可以是任何小写的 HTTP 请求方法,包括get
、post
、put
、delete
等等PATH
是客户端访问的 URI,例如/
或/about
HANDLER
是路由被触发时的回调函数,在函数中可以执行相应的业务逻辑
实现的小例子
const express = require("express");
const hostname = "localhost";
const port = 3000;
const app = express();
app.get("/", (req, res) => {
res.send("Hello World");
});
app.listen(port, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
复制代码
执行npm run start
,(提前在package.json中对start进行了配置了)
可以看到程序执行了,打开http://localhost:3000进行查看
可以看到GET请求是成功的
中间件
首先客户端向服务器发起请求,然后服务器依次执行每个中间件,最后到达路由,选择相应的逻辑来执行。
有两点需要特别注意:
-
中间件是按顺序执行的,因此在配置中间件时顺序非常重要,不能弄错
-
中间件在执行内部逻辑的时候可以选择将请求传递给下一个中间件,也可以直接返回用户响应
Express中间件的定义
在Express中,中间件就是一个函数:
function someMiddleware(req, res, next) {
// 自定义逻辑
next();
}
复制代码
三个参数中,req
和 res
就是前面提到的 Request 请求对象和 Response 响应对象;而 next
函数则用来触发下一个中间件的执行。
注意
如果忘记在中间件中调用 next
函数,并且又不直接返回响应时,服务器会直接卡在这个中间件不会继续执行下去哦!
在 Express 使用中间件有两种方式:全局****中间件和路由****中间件。
全局中间件
通过app.use
函数就可以注册中间件
路由中间件
通过在路由定义时注册中间件,此中间件只会在用户访问该路由对应的 URI 时执行,例如:
app.get('/middleware', someMiddleware, (req, res) => {
res.send('Hello World');
});
复制代码
那么用户只有在访问 /middleware
时,定义的 someMiddleware
中间件才会被触发,访问其他路径时不会触发。
编写中间件
接下来我们就开始实现第一个 Express 中间件。功能很简单,就是在终端打印客户端的访问时间、 HTTP 请求方法和 URI,名为 loggingMiddleware
。代码如下:
// ...
const app = express();
function loggingMiddleware(req, res, next) {
const time = new Date();
console.log(`[${time.toLocaleString()}] ${req.method} ${req.url}`);
next();
}
app.use(loggingMiddleware);
app.get('/', (req, res) => {
res.send('Hello World');
});
// ...
复制代码
中间件不仅可以读取 req
对象上的各个属性,还可以添加新的属性或修改已有的属性(后面的中间件和路由函数都可以获取),能够很方便地实现一些复杂的业务逻辑(例如用户鉴权)。
处理404和服务器错误
这张示意图和之前的图有两点重大区别:
-
每个路由定义本质上是一个中间件(更准确地说是一个中间件****容器,可包含多个中间件),当 URI 匹配成功时直接返回响应,匹配失败时继续执行下一个路由
-
每个中间件(包括路由)不仅可以调用
next
函数向下传递、直接返回响应,还可以抛出异常 -
对于 404,只需在所有路由之后再加一个中间件,用来接收所有路由均匹配失败的请求
-
对于错误处理,前面所有中间件抛出异常时都会进入错误处理函数,可以使用 Express 自带的,也可以自定义。
处理 404
在 Express 中,可以通过中间件的方式处理访问不存在的路径:
app.use('*', (req, res) => {
// *表示匹配任何路径,将此中间件放在所有路由后面
});
// 中间件和其他路由 ...
app.use('*', (req, res) => {
res.status(404).render('404', { url: req.originalUrl });
});
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).render('500');
});
app.listen(port, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
复制代码
使用子路由
在 Express 中,我们可以通过子路由 Router
来实现
*
express.Router
可以理解为一个迷你版的 app
对象,但是它功能完备,同样支持注册中间件和路由:
// 注册一个中间件
router.use(someMiddleware);
// 添加路由
router.get('/hello', helloHandler);
router.post('/world', worldHandler);
复制代码
最后只需要把Router作为中间件加入到app中
*
这样router
下的全部路由都会加到/say
之下,相当于:
app.get('/say/hello', helloHandler);
app.post('/say/world', worldHandler);
复制代码
体会
这只是对express的基本使用的小体会,express博大精深,后续进阶的文档会继续补充的