Express 是一个简洁而灵活的 Node.js Web 应用框架,提供了强大特性帮助你创建各种 Web 应用和 API
对于前端程序员来说,最常见的两种服务器,分别是:
⚫ Web 网站服务器:专门对外提供Web 网页资源的服务器。
⚫ API 接口服务器:专门对外提供API 接口的服务器。
使用Express,我们可以方便、快速的创建Web 网站的服务器或API 接口的服务器
1.express()实例
创建一个 Express 应用程序。
express()
函数是express
模块导出的顶级函数。
1.express.static():托管静态资源
express 提供了一个非常好用的函数,叫做 express.static(),通过它,我们可以非常方便地创建一个静态资源服务器,例如,通过如下代码就可以将 public 目录下的图片、CSS 文件、JavaScript 文件对外开放访问了:
注意:Express 在指定的静态目录中查找文件,并对外提供资源的访问路径。
因此,存放静态文件的目录名不会出现在 URL 中。
如果要托管多个静态资源目录,请多次调用 express.static() 函数:
访问静态资源文件时,express.static() 函数会根据目录的添加顺序查找所需的文件。
如果希望在托管的静态资源访问路径之前,挂载路径前缀,则可以使用如下的方式:
现在,你就可以通过带有 /public 前缀地址来访问 public 目录中的文件了:
http://localhost:3000/public/images/kitten.jpg
http://localhost:3000/public/css/style.css
http://localhost:3000/public/js/app.js
2.express.Router()
创建一个新的 router 对象,不再将路由挂载到app身上而是挂载到router实例身上
2.应用(app)
app
对象通常表示 Express 应用程序。通过调用 Express 模块导出的顶级express()
函数来创建它:
1.app.get()
通过 app.get() 方法,可以监听客户端的 GET 请求,具体的语法格式如下:
2.app.post()
通过 app.post() 方法,可以监听客户端的 POST 请求,具体的语法格式如下
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.get('/index', (req, res) => {
res.send({ name: '张三', age: 18 });
});
app.post('/txt', (req, res) => {
res.send('这是post请求');
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
3.app.use([path,] callback [, callback...])
在指定路径挂载指定的 中间件 函数或函数:当请求路径的基数与 path
匹配时执行中间件函数。
4.app.listen()
监听端口号
3.请求(req)
req
对象表示 HTTP 请求,并具有请求查询字符串、参数、正文、HTTP 标头等的属性。在本文档中,按照惯例,该对象始终称为req
(HTTP 响应为res
),但其实际名称由您正在使用的回调函数的参数确定。
1.req.query
通过 req.query对象,可以访问到客户端通过查询字符串的形式,发送到服务器的参数
2.req.params
通过 req.params对象,可以访问到 URL 中,通过 :匹配到的动态参数
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
console.log(req.query);
// { name: 'zs', age: '18' }
res.send('Hello World!');
});
app.get('/index/:id', (req, res) => {
console.log(req.params);
// { id: '4' }
res.send({ name: '张三', age: 18 });
});
app.post('/txt', (req, res) => {
res.send('这是post请求');
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
4.响应(res)
res
对象表示 Express 应用程序在收到 HTTP 请求时发送的 HTTP 响应。
1.res.send()
通过 res.send() 方法,可以把处理好的内容,发送给客户端:
5.路由(router)与中间件(Middleware)
1.路由
1.基本用法
在 Express 中,路由指的是客户端的请求与服务器处理函数之间的映射关系。
路由匹配的注意点:
①按照定义的先后顺序进行匹配
②请求类型和请求的URL同时匹配成功,才会调用对应的处理函数
在 Express 中使用路由最简单的方式,就是把路由挂载到 app 上
但是在实际API开发中我们都会模块化路由
// 引入express
const express = require('express');
// 创建路由
const router = express.Router();
// 路由的使用
router.get('/index', (req, res) => {
res.send('这是index页面');
});
router.post('/user', (req, res) => {
res.send('这是user页面');
});
// 导出路由
module.exports = router;
const express = require('express');
//导入路由
const userRouter = require('./router');
const app = express();
const port = 3000;
//使用路由
app.use('/api', userRouter);
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
2.中间件
1.基本用法
Express 的中间件,本质上就是一个 function 处理函数,Express 中间件的格式如下
注意:中间件函数的形参列表中,必须包含 next 参数。而路由处理函数中只包含 req 和 res。
const express = require('express');
const app = express();
//使用中间件1
app.use((req, res, next) => {
console.log('调用中间件1');
next();
});
//使用中间件2
app.use((req, res, next) => {
console.log('调用中间件2');
next();
});
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(3001, () => {
console.log(`Express app listening at http://localhost:3001`);
});
可以在路由中,通过如下两种等价的方式,使用多个局部中间件:
const express = require('express');
const app = express();
function mv(req, res, next) {
console.log('调用了局部中间件');
next();
}
//使用中间件并携带数据
app.use((req, res, next) => {
const data = new Date().toLocaleDateString();
req.timer = data;
console.log('调用中间件1');
next();
});
//使用中间件2
app.use((req, res, next) => {
console.log('调用中间件2');
next();
});
app.get('/', (req, res) => {
res.send(`访问接口的日期为 ${req.timer}`);
});
app.get('/index', mv, (req, res) => {
res.send('Hello Index!');
});
app.listen(3001, () => {
console.log(`Express app listening at http://localhost:3001`);
});
2.五个注意事项
①一定要在路由之前注册中间件(错误级别中间件例外)
②客户端发送过来的请求,可以连续调用多个中间件进行处理
③执行完中间件的业务代码之后,不要忘记调用 next() 函数
④为了防止代码逻辑混乱,调用 next() 函数后不要再写额外的代码
⑤连续调用多个中间件时,多个中间件之间,共享req 和 res 对象
3.中间件的分类
1.应用级别中间件
通过 app.use() 或 app.get() 或app.post() ,绑定到 app 实例上的中间件,叫做应用级别的中间件,代码示例如下:
2.路由级别中间件
3.错误级别中间件
4.Express内置的中间件
自 Express 4.16.0 版本开始,Express 内置了 3 个常用的中间件,极大的提高了 Express 项目的开发效率和体验:
①express.static快速托管静态资源的内置中间件,例如: HTML 文件、图片、CSS 样式等(无兼容性)
②express.json解析 JSON 格式的请求体数据(有兼容性,仅在 4.16.0+ 版本中可用)
③express.urlencoded解析 URL-encoded 格式的请求体数据(有兼容性,仅在 4.16.0+ 版本中可用)
5.第三方中间件
非 Express 官方内置的,而是由第三方开发出来的中间件,叫做第三方中间件。在项目中,大家可以按需下载并配置第三方中间件,从而提高项目的开发效率。
例如:在 express@4.16.0 之前的版本中,经常使用 body-parser 这个第三方中间件,来解析请求体数据。使用步骤如下:
①运行 npm install body-parser安装中间件
②使用 require导入中间件
③调用 app.use() 注册并使用中间件
注意:Express 内置的 express.urlencoded中间件,就是基于 body-parser 这个第三方中间件进一步封装出来的。
6.自定义中间件
// 导入 Node.js 内置的 querystring 模块
const qs = require('querystring');
const bodyParser = (req, res, next) => {
// 定义中间件具体的业务逻辑
// 1. 定义一个 str 字符串,专门用来存储客户端发送过来的请求体数据
let str = '';
// 2. 监听 req 的 data 事件
req.on('data', (chunk) => {
str += chunk;
});
// 3. 监听 req 的 end 事件
req.on('end', () => {
// 在 str 中存放的是完整的请求体数据
// console.log(str)
// TODO: 把字符串格式的请求体数据,解析成对象格式
const body = qs.parse(str);
req.body = body;
next();
});
};
module.exports = bodyParser;