Express
Express
1、什么是Express
Express时基于Node.js平台,快速、开放、极简的Web开发框架
通俗的理解:Express的作用和Node.js内置的http模块类似,是专门用来创建web服务器的
Express的本质:是一个npm 上的第三方包,提供了快速创建Web服务器的便捷方法
Express官网:https://www.expressjs.com.cn/ 本人使用Express 4.17.1 版本进行学习
2、安装Express
npm i express@4.17.1
3、使用Express创建基本的服务器
// 1.导入express
const express = require('express')
// 2.创建web服务器
const app = express()
// 4.监听客户端的 GET 和 POST 请求,并向客户端响应具体的内容
app.get('/user',(req,res)=>{
//调用express提供的res.send()方法,向客户端响应一个JSON对象
res.send([{name:'zs',age:20,gender:'男'},{name:'ls',age:22,gender:'女'}])
})
app.get('/',(req,res)=>{
// 通过req.query可以获取到客户端发过来的查询参数
//默认情况下,req.query是一个空对象
res.send(req.query)
})
app.get('/user/:id/:name',(req,res)=>{
// 通过req.params,可以通过 :参数名 的形式 匹配动态参数值
res.send(req.params)
})
app.post('/user',(req,res)=>{
res.send("post请求成功")
})
// 3.启动web服务器
app.listen('80',()=>{
console.log("express server running at http:127.0.0.1");
})
4、nodemon的使用
好处:代码被修改后会被nodemon监听到,从而实行自动重启项目的效果
nodemon的安装,在终端内输入:
npm i -g nodemon
终端运行项目:
nodemon 项目文件名
遇见问题vscode权限不够:
解决办法:
以管理员身份打开PowerShell(按住shift不要松 然后右击桌面空白区域, 就可以看到打开PowerShell的选择项了)
打开后,输入get-ExecutionPolicy,回复Restricted,表示状态是禁止的
然后执行:set-ExecutionPolicy RemoteSigned
选择Y
5、Express路由
5.1.路由的概念
5.2.路由的简单使用
const express = require('express')
// 创建web服务器,并命名为app
const app = express()
// 挂载路由
app.get('/',(req,res)=>{
res.send("get succeed")
})
app.post('/',(req,res)=>{
res.send('post succeed')
})
// 启动web服务器
app.listen('80',()=>{
console.log('express server running at http://127.0.0.1');
})
5.3.创建路由模块
0.3router.js:
// 1、导入express
const express = require('express')
// 2、创建路由对象
const router = express.Router()
router.get('/user/list',(req,res)=>{
res.send('Get user list')
})
// 3、挂载具体路由
router.post('/user/add',(req,res)=>{
res.send('Add new user')
})
//4、向外导出路由对象
module.exports = router
使用路由:
02.使用模块化路由.js:
const express = require('express')
const app = express()
// 1、导入路由模块
const router = require('./03.router')
// 2、注册路由模块
app.use('/api',router)
app.listen(80,()=>{
console.log('express running at http://127.0.0.1')
})
5.4.使用路由前缀:
app.use('/api',router)
6、Express中间件
6.1.Express的中间的本质
6.2.next函数的作用:
6.3.全局生效的中间件:
客户端发起的任何请求,到达服务器之后,都会出发的中间件,叫做全局生效的中间件。
通过调用app.use(中间件函数),即可定义一个全局生效的中间,代吗如下
const express = require('express');
const app = express()
//全局生效中间件
// const mw = function(req,res,next){
// console.log("这是最简单的路由中间件");
// next()
// }
// app.use(mw)
//全局生效中间件的简写形式:
app.use((req,res,next)=>{
console.log('这是最简单的路由中间件2');
next()
})
app.get('/',(req,res)=>{
console.log('get succeed');
res.send('get succeed')
})
app.listen(80,()=>{
console.log("express server running at http://127.0.0.1");
})
运行结果:会最先运行中间件,然后再运行get/post请求
6.4.中间件的作用:
实例代码:
const express = require('express');
const app = express()
app.use((req, res, next) => {
const time = Date.now()
req.startTime = time
next()
})
app.get('/', (req, res) => {
res.send('05 --- get succeed:' + req.startTime)
})
app.post('/', (req, res) => {
res.send('05 --- post succeed:' + req.startTime)
})
app.listen(80, () => {
console.log("express server running at http://127.0.0.1");
})
6.5.局部生效的中间件
const express = require('express')
const app = express()
// 定义中间件函数1
const mw1 = (req,res,next)=>{
console.log("调用了局部中间件1");
next()
}
// 定义中间件函数2
const mw2 = (req,res,next)=>{
console.log("调用了局部中间件2");
next()
}
// 局部中间件的使用方法,只在此路由中生效
app.get('/Home',[mw1,mw2],(req,res)=>{
res.send('Home page')
})
// 使用多个局部中间件可以用 [] 或者单独写都可以
// app.get('/Home',mw1,mw2,(req,res)=>{
// res.send('Home page')
// })
// 中间件的局部调用不会影响↓这个路由
app.get('/user',(req,res)=>{
res.send('User Page')
})
app.listen(80,()=>{
console.log("express server running at http://127.0.0.1");
})
6.6.使用中间件的注意事项
- 一定要在路由之前注册中间件
- 客户端发送过来的请求,可以连续调用多个中间件进行处理
- 执行完成中间件的业务代码之后,不要忘记调用next()函数
- 为了放置代码逻辑混乱,调用next()函数后不要再写额外的代码
- 连续调用多个中间件时,多个中间件之间,共享req和res对象
6.7中间件的分类
1.应用级别中间件:
通过app.user()或 app.get 或 app.post() 绑定到app实例上中间件,叫做应用级中间件
2.路由级别的中间件:
3.错误级别中间件
作用:专门用来捕获整个项目中发生的错误,从而防止项目一次奔溃的问题
const express = require('express')
const app = express()
app.get('/',(req,res)=>{
// 认为制造错误
throw new Error("系统内部错误")
res.send('index page')
})
// 定义错误级别的中间件,捕获整个项目的异常错误,从而防止程序的奔溃
app.use((err,req,res,next)=>{
console.log('发生了错误:'+err.message);
res.send('Error:'+err.message)
})
app.listen(80,()=>{
console.log('express server running at http://127.0.0.1');
})
4.内置中间件的使用:
POST Json类型的数据:
POST urlencoded类型数据:
服务器收到的数据为:
示例代码:
const express = require('express')
const app = express()
// 注意:出了错误级别的中间件,其他中间件,必须在路由之前进行配置
// 通过express.json() 这个中间件,解析表单中的json格式的数据
app.use(express.json())
// 通过express.urlencoded()中间件,来解析表单中的url-encoded格式的数据
app.use(express.urlencoded({extended:false}))
app.post('/user',(req,res)=>{
// 在服务器,可以使用req.body这个属性,来接收客户端发来的请求数据
// 默认情况下,如果不配置解析表单数据的中间件,则req.body 默认等于undefined
console.log(req.body);
res.send('ok')
})
app.post('/book',(req,res)=>{
// 在服务器端:可以通过req.body来获取json格式的表单数据和url-encoded格式的数据
console.log(req.body);
res.send('ok')
})
app.listen(80,()=>{
console.log('express server running at http://127.0.0.1');
})
6.8自定义中间件
实现步骤:
1.定义中间件
2.监听req的data时间
3.监听req的end时间
4.使用querystring模块解析请求体的数据
5.将解析出来的对象挂载伟req.body,以便于后续的使用
6.将自定义中间件封装为模块
示例代码:
const express = require('express')
const app = express()
// 导入Node.js内置的querystring模块
const qs = require('querystring')
app.use((req,res,next)=>{
//自定义中间件的业务逻辑
// 1.定义一个str字符串,专门用来存储客户端发过来的请求体数据
let str = ''
// 2.监听req的data时间
req.on('data',(chunk)=>{
str += chunk
})
// 3.监听req的end时间
req.on('end',()=>{
// 在str中存放的是完整的请求体数据
// TODO:把字符串格式的请求体数据,解析成对象格式
const body = qs.parse(str)
req.body = body
console.log(req.body)
next()
})
})
app.post('/user',(req,res)=>{
res.send('ok')
})
app.listen(80,()=>{
console.log('express server running at http://127.0.0.1');
})
对自定义中间件进行模块化的封装
14.custom-body-parser.js:
// 导入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中存放的是完整的请求体数据
// TODO:把字符串格式的请求体数据,解析成对象格式
const body = qs.parse(str)
req.body = body
console.log(req.body)
next()
})
}
module.exports = bodyParser
使用自定义中间件模块:
const express = require('express')
const app = express()
// 1.导入自己封装的中间件模块
const cuntomBodyParser = require('./14.custom-body-parser')
// 2.将自定义的中间件函数,注册为全局可用的中间件
app.use(cuntomBodyParser)
app.post('/user',(req,res)=>{
res.send('ok')
})
app.listen(80,()=>{
console.log('express server running at http://127.0.0.1');
})
7使用Express写接口
1.使用Express写接口
apiRotter.js
const express = require('express')
const router = express.Router()
//在这里挂载对应的路由
router.get('/get',(req,res)=>{
// 通过req.query获取客户端查询字符串,发送到服务器的数据
const query = req.query
//调用res.send()方法,向客户端响应处理的结果
res.send({
status:0, // 0 表示处理成功 1 表示处理失败
msg:'GET 请求成功',
data:query //需要响应黑客户端的数据
})
})
router.post('/post',(req,res)=>{
// 通过req.body 或许请求体中包含的url-urlencoded格式的数据
const body = req.body
res.send({
status:0,
msg:'POST 请求成功',
data:body
})
})
module.exports = router
使用apiRouter:
const express = require('express')
const app = express()
// 配置解析表单数据的中间件
app.use(express.urlencoded({extended:false}))
//导入路由模块
const router = require('./16.apiRouter')
//把路由模块注册到app上
app.use('/api',router)
app.listen(80,()=>{
console.log('express server running at http://127.0.0.1');
})
2.跨域的问题:
此链接可以获取在线的JQuery https://staticfile.org/
案例:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Title</title>
<script src="https://cdn.staticfile.org/jquery/1.10.0/jquery.min.js"></script>
</head>
<body>
<button id="btnGET">GET</button>
<button id="btnPOST">POST</button>
<script>
$(function () {
$('#btnGET').on('click', function () {
$.ajax({
type: 'GET',
url: 'http://127.0.0.1/api/get',
data: { name: 'zs', age20 },
success: function (res) {
console.log(res);
}
})
})
})
$(function () {
$('#btnPOST').on('click', function () {
$.ajax({
type: 'GET',
url: 'http://127.0.0.1/api/post',
data: { bookname: '三国演义', author: '罗贯中' },
success: function (res) {
console.log(res);
}
})
})
})
</script>
</body>
</html>
上面的GET和POST存在跨域问题,解决接口跨域问题的方案有两种:
1.CORS(主流的解决方案,推荐使用)
2.JSONP(有缺陷的解决方案:只支持GET请求)
3.使用cors中间件解决跨域的问题
1.cors中间件的安装和使用
npm i cors
使用 const cors = require('cors') 导入中间件
在路由之前调用 app.use(cors()) 配置中间件
安装完成后将上面的代码完善后便可以解决跨域问题了:
const express = require('express')
const app = express()
// 配置解析表单数据的中间件
app.use(express.urlencoded({extended:false}))
//在路由之前配置中间件,从而解决接口跨域问题
const cors = require('cors')
app.use(cors())
//导入路由模块
const router = require('./16.apiRouter')
//把路由模块注册到app上
app.use('/api',router)
app.listen(80,()=>{
console.log('express server running at http://127.0.0.1');
})
4.什么是CORS?
2.CORS的注意事项
3.CORS响应头部 -Access-Control-Allow-Origin
4.CORS响应头部-Access-Control-Allow-Headers
5.CORS响应头部-Access-Control-Allow-Methods
5.CORS的分类
1.简答请求
2.预检请求
3.简答请求和预检请求的区别
6.JSONP写接口
1.JSONP的概念与特点
2.创建JSONP接口的注意事项
代码的具体实现:
//鼻血在配置cors中间件之前,配置 JSONP 的接口
app.get('/api/jsonp',(req,res)=>{
// TODO:定义JSONP接口具体的实现过程
// 1.得到函数的名称
const funName = req.query.callback
//2.定义要发送到客户端的数据对象
const data = {name:'zs',age:22}
// 3.拼接出一个函数的调用
const scriptStr = `${funName}(${JSON.stringify(data)})`
// 4.把拼接出的字符串,响应给客户端
res.send(scriptStr)
})
posted on 2022-03-27 21:11 IT丶Hatcher 阅读(371) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix