Node.js 第四天
一、Express插件
1、什么是 Express
基于 Node.js 平台,快速、开放、极简的 Web 开发框架, 本质上就是一个 npm 的第三方包, 给我们提供了快速创建 web 服务器的方法
2、Express的应用场景
开发 Web 网站服务器
API 接口服务器
3、安装 Express
在项目的根目录下, 执行命令: npm i express@4.17.1
4、Express使用
- 基本使用及对get、post请求进行监听
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| const express = require('express');
const app = express();
app.get('/userinfo', (req, res) => { res.send({ name: 'xh', age: 12, height: 155 }) });
app.get('/', (req, res) => { res.send({ name: 'xh', age: 12, height: 155 }) });
app.post('/login', (req, res) => { res.send('登录成功!') })
app.listen(3006, () => { console.log('启动服务成功:http://localhost:3006'); })
|
- 获取动态参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const express = require('express');
const app = express();
app.get('/my/article/deletecate/:id/:name', (req, res) => { console.log(req.params.id, req.params.name); res.send(req.params); });
app.listen(3006, () => { console.log('服务运行:http://localhost:3006/my/article/deletecate/20/zs'); })
|
托管动态资源并添加资源前缀
注意:优化为绝对地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const express = require('express'); const path = require('path');
const app = express();
app.use('/public', express.static(path.join(__dirname,'./assets')));
app.listen(3006, () => { console.log('服务运行:http://localhost:3006/public'); })
|
二、nodemon包
每次修改 node.js 服务端代码都需要重新启动服务, 比较繁琐, nodemon 插件可以实时监测文件的动态变化,
并当文件内容变化时自动重启服务
全局安装:
npm i -g nodemon
使用方法:
nodemon index.js
三、路由
1、定义
路由在广义上理解就是指一种映射关系, 在 node.js 中指的是客户端的请求和服务端处理函数的映射关系,Express 路由包括 3 部分: 请求的 URL, 请求的类型, 处理函数
2、定义路由方法
app.Method(URL, handler)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const express = require('express');
const router = express.Router();
router.get('/', (req, res) => { res.send('hello!') }); router.get('/api', (req, res) => { res.send('world') }); router.post('/api', (req, res) => { res.send('hello!123') });
module.exports = router;
|
1 2 3 4 5 6 7 8 9 10 11 12
| const express = require('express'); const router = require('./10-创建路由模块');
const app = express();
app.use('/my', router);
app.listen(3006, () => { console.log('运行成功:http://localhost:3006/my'); })
|
四、中间件
1、什么是中间件?
泛指业务流程的中间处理环节, Express 的中间件即是指响应数据的中间环节, 本质上就是一个处理函数
2、中间件的参数列表
包含 req 请求对象, res 响应对象 和 next 回调函数, 注意路由处理函数中没有 next 参数
3、next 参数的作用
用来实现多个中间件连续调用的关键, 一个中间件函数内必须调用 next() 将控制权传递给下一个中间件功能, 否则该请求将被挂起。
1 2 3 4 5 6 7 8 9 10 11 12 13
| const middleware = (req, res, next) => { console.log('正在处理请求'); next(); };
app.use(middleware);
app.use((req, res, next) => { console.log('执行第二个中间件'); next(); });
|
4、中间件的范围
- 全局中间件: 任何请求到达服务器之后都会触发的中间件
- 局部中间件: 只有匹配当前路由的请求到达服务器才会触发的中间件
1 2 3 4 5 6 7 8 9 10
| const mw = (req, res, next) => { console.log('使用了局部中间件'); next(); };
app.get('/', mw, (req, res) => { res.send("hello") });
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| const mw1 = (req, res, next) => { req.name = 'zs'; req.pwd = 'asd455'; res.age = '20'; console.log('执行第一个中间件'); next(); }
const mw2 = (req, res, next) => { console.log('执行第二个中间件'); next(); }
app.get('/', [mw1, mw2], (req, res) => { console.log(req.name, req.pwd, res.age); res.send("hello") });
|
5、中间件的注意事项
全局中间件的注册要放在路由定义之前
对于一个客户端的发送过来的请求, 可以调用多个中间件进行处理
中间件的处理函数中一定要有 next() 调用
next 函数之后不用再写和业务无关的代码
多个中间件之间共享 req 和 res 对象
6、中间件的分类
应用层中间件
路由级中间件 router(url,中间件,fn())
错误处理中间件 (err,req,res,fn())
注意: 一定要放在所有路由之后
1 2 3 4 5 6 7
| app.use((err, req, res, next) => { if (err) { console.log('错误信息:' + err.message); res.send({ status: 1, message: err.message }) } })
|
内置中间件
第三方中间件
7、内置中间件
express.static() 快速托管静态资源的中间件
express.json() 解析客户端传递的 json 格式的请求体数据,处理post表单提交的application/json 格式的数据
express.urlencoded() 解析客户端传递的 urlencoded 编码形式的请求体数据,处理post表单提交的application/x-www-form-urlencode 格式的数据
1 2 3 4 5
| app.use(express.json());
app.use(express.urlencoded({ extended: false }))
|
8、第三方中间件
非 Express 内置给我们的, 而是由第三方个人或公司开发的中间件, 我们可以先下载再配置来进行使用
示例: 使用 body-parse 这个中间件来解析请求体的数据
运行命令下载 npm i body-parse
使用 require() 方法引入
使用 app.use() 方法注册
9、自定义中间件
实现步骤:
定义全局中间件
监听 req 的 data 事件
监听 req 的 end 事件
使用 querystring 模块解析请求体数据
把解析后的数据挂载到 req.body 上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| const qs = require('querystring'); const bodyParser = (req, res, next) => {
let str = '';
req.on('data', (chunk) => { console.log(chunk); str += chunk; }); req.on('end', () => { console.log(str); const type = req.get('Content-Type'); console.log(type); if (type === 'application/json') { req.body = JSON.parse(str); } else if (type === 'application/x-www-form-urlencoded') { req.body = qs.parse(str); } next() });
};
module.exports = bodyParser;
|
10、cors概念了解
定义
(Cross-Origin Resource Sharing) 跨域资源共享, 由一系列的 HTTP 响应头组成, 这些响应头决定了浏览器是否阻止前端 js 代码发出跨域请求。
CORS 的响应头部
(1) Access-Control-Allow-Origin: url/* 指定了允许访问该资源的url
(2) Access-Control-Allow-Headers: a, b, c 指定了允许发送哪些请求头
(3) Access-Control-Allow-Methods: GET, POST 指定了允许发送何种类型的请求
cors 请求的分类
简单请求: 请求方式为 GET/POST/HEAD 之一; 无自定义请求头字段
预检请求: 请求方式不为 GET/POST/HEAD 之一; 存在自定义请求头字段; 发送了 application/json 格式数据
浏览器会先发送一个 OPTIONS 请求进行预检, 以确认服务器是否允许该实际请求, 完成后再发送真正的请求
11、案列:express写接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| const express = require('express'); const router = express.Router();
router.get('/get', (req, res) => { const data = req.query; console.log(data); res.send({ status: 0, message: '获取数据成功!', data }) });
router.post('/post', (req, res) => { const data = req.body; console.log(data); res.send({ status: 0, message: '提交数据成功!', data }) });
router.delete('/delete', (req, res) => {
res.send({ status: 0, message: '删除数据成功!',
}) }); module.exports = router;
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| const express = require('express');
const cors = require('cors'); const app = express();
const router = require('./19-apiRouter');
app.use(express.urlencoded({ extended: false })); app.use(express.json());
app.get('/api/jsonp', (req, res) => { console.log(req.query.callback); res.send(` ${ req.query.callback}({name:'zs',age:10}) `) })
app.use(cors());
app.use('/api', router);
app.use((req, res, next) => { res.send('404 页面找不到了'); next() })
app.use((err, req, res, next) => { if (err) { res.send({ status: 1, message: err.message }) }; next(); })
app.listen(3006, () => { console.log('服务运行在:http://localhost:3006'); });
|
运行文件二,在postman中进行测试