node 之 express
什么是express?
Express 是一个简洁、灵活的 nodejs 的 web 应用开发框架。本身是由一个路由和中间件组成的框架
特点:
1.易上手
2.高性能
3.扩展性强,可以自由的拆分和安装模块
什么是框架?
大白话:就是把常用的操作封装在里面,这样就可以不用重复书写,直接使用框架里面提供的功能即可
安装express
1 | npm i express |
注意事项:不能安装在express文件夹下,否则会失败
使用express构造web服务器
1.加载express模块
2.创建express服务器
3.启动服务器
4.监听浏览器请求并进行处理
1 2 3 4 5 6 7 8 9 10 | //加载express模块 const express = require( 'express' ) const app = express(); app.listen(8000,()=>{ console.log( 'express服务器开始工作了' ) }) app. get ( '请求地址' ,(req,res)=>{} ) app.post( '请求地址' ,(req,res)=>{ }) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | const express = require( "express" ); const app = express(); app.listen(8001, () => { console.log( "server is running " ); }); app. get ( "/" , (req, res) => { res.end( "get请求方式" ); }); app.post( "/" , (req, res) => { res.end( "post请求方式" ); }); <strong>说明:使用nodemon 文件名.js </strong> |
express封装的新方法
重点: express之所以能够实现web服务器的搭建,是因为其内部对核心模块http进行封装
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 | express express. static () --开放静态资源 express.urlencoded() -- 获取post请求体 ... app app. get () --处理客户端的 get 请求 app.post() --处理客户端的post请求 app.use() --设置应用级别的配置 ... req req.body --获取post请求体 req. params --获取 get 请求动态参数 req.query -- 获取 get 请求参数(获取查询字符串参数) ...... res res.end( 'helll' ) ;响应结果 http源码 只能填字符窜参数 (res.end( '中文会乱码' )) //还需要设置编码格式 --res.end([ 'aaa' , 'cccc' ]) res.sendFile( '文件的绝对路径' ) --读取文件,并将结果响应 --res.sendFile(path. join (__dirname, 'books.json' )) res.json({name: 'zs' }) //响应json对象(常用) res.send( 'hello' ) //会自动设置响应头,做出响应 --res.send([ 'aaa' , 'bbb' , 'ccc' ]) 对于数组,对象等,会自动json.stringify() res. set ({ 'Author' , 'zhangsan' }) -- 设置响应头,不能设置状态码 |
请求案例(req)
get请求方式的参数获取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | let express = require( "express" ); let app = express(); app.listen( "8003" , () => { console.log( "8003服务器已开启" ); }); //查询字符串 获取为对象 配置时与请求地址无关 //http://localhost:8003/index?name=zs&age=19 app. get ( "/index" , (req, res) => { res.send(req.query); }); //动态参数 获取为对象 配置时与请求地址有关 //http://localhost:8003/login/zs/19 app. get ( "/login/:name/:age" , (req, res) => { res.send(req. params ); }); |
post请求方式的参数获取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | let express = require( "express" ); let app = express(); app.listen( "8003" , () => { console.log( "8003服务器已开启" ); }); const multer = require( "multer" ); const path = require( "path" ); // const upload = multer({ dest: "路径" }); //使用绝对路径 const upload = multer({ dest: "./upload" }); app.post( "/bb" , upload.single( "img" ), (req, res) => { //注意:这里的img对应的是post传参对应的参数名 // res.send(req.body);//用来获取post请求的数据 res.send(req.file); //获取文件相关信息 `{ "fieldname" : "img" , "originalname" : "3.jpg" , "encoding" : "7bit" , "mimetype" : "image/jpeg" , "destination" : "./upload" , "filename" : "9d18f0c0d52edb7f6fbf13fa0f55b7cb" , "path" : "upload\\9d18f0c0d52edb7f6fbf13fa0f55b7cb" , "size" :63519 }`; });注意:如下图分析1/若是含有文件上传的功能,那么就是form-data格式2/若没有上传,就可以选 x-www-form-urlencoded 格式 |
post 请求总结
1 2 3 4 5 6 7 8 | post请求体的类型(content-type) 1/application/x-www-form-urlencoded 比如:id=1&name=zs&age=20 form表单中通过submit按钮提交是这种应用级配置 2/form-data 比如,提交的是formData对象 注意:这里的提交的formData是通过jquery$( 'from' ).serilize()然后作为参数提交(有待进一步确认) 3/application/json 比如,提交的是{ "id" :1, "name" : "zs" , "age" :20} 服务器端接收不同类型的请求体,应用级配置的方式也不一样 urlencoded --->app.use(express.urlencoded({extended: false })) 对应post上面的1 application/json ---->app.use(express.json()) 对应的是post上面的2 form-data ----> 服务端使用第三方模块处理(multer) |
响应案例(res)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | //响应结果案例 //导入 const express = require( "express" ); const path = require( "path" ); //创建服务 const app = express(); //启动 app.listen( "8002" , () => { console.log( "8002端口服务器在运行" ); }); //配置请求响应 app. get ( "/index" , (req, res) => { // res.end("ok-今天天气真不错"); // res.end({ name: "zs" }); //报错 // res.send("ok-今天天气真不错"); // res.sendFile(path.join(__dirname, "./Z01.js")); // res.json({ name: "zs" }); }); |
静态资源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | //导入express模块 const express = require( "express" ); //创建服务 const app = express(); app.listen( "3006" , () => { console.log( "书籍系统正在启用中......" ); }); // app.get("/api/getbooks", (req, res) => { // res.send(""); // }); app.use(express. static ( "../zhxm" )); //切记,这里的路径是相对执行文件而言的注意:多个静态资源目录可以通过多次配置来实现开放问题:不同路径下,有多个文件,重名怎么办app.use('/p',express.static('./public')) |
路由
什么是路由?
举例说明:拨打电话10086,不同的按键有不同的业务,所以在这里,路由是按键与服务之间的映射关系
实质是: url地址和逻辑(回调函数),之间一一对应的映射关系.
1 2 3 4 5 6 7 8 9 10 | //引入模块 const express = require( 'express' ) //创建路由对象 const router = express.Router(); //路由配置 router. get ( '/index' ,req,res)=>{ }) //导出路由 module.exports = router |
模块化路由
为了方便对路由进行模块化的管理,express不建议将路由直接挂载到app上,而是推荐将路由抽离为单独的模块,将路由抽离为单独模块
1.创建路由模块对应的.js文件
1.创建router/login.js 存放 登录 注册 验证码三个路由
2.创建router/heroes.js存放 和英雄相关的所有路由
2.调用express.Router()函数创建路由对象
1 2 | const express = require( 'express' ) const router = express.Router() |
3.向路由对象上挂载具体的路由
1 2 | router. get ( 'xx/xx' ,(req,res)=>{}) router.post( 'xx/xx' ,(req,res)=>{}) |
4.使用module.exports向外共享路由对象
1 | module.exports = router |
5.使用app.use() 函数注册路由模块 --app.js
1 2 3 | //app.js中,将路由导入,注册路由 const login = require( './router/login.js' ) app.use(login) |
实际案例:
user.js
const express = require("express"); const router = express(); router.get("/getUser", (req, res) => { res.send("getUser请求通过"); }); module.exports = router;
stu.js
const express = require("express"); const router = express(); router.get("/getStu", (req, res) => { res.send("getStu请求通过"); }); module.exports = router;
app.js(入口)
const express = require("express"); const app = express(); app.listen("8009", () => { console.log("8009服务已经开启......"); }); const stu = require("./stu"); const user = require("./user"); app.use("/api", stu); app.use("/my", user);
在页面上分别输入可以请求成功
http://localhost:8009/api/getStu
http://localhost:8009/user
中间件
本来正常的过程是前端发送请求到后端,后端对这个请求进行处理,然后给前端返回响应。那么中间件的作用就是在接收到前端的请求后,作出一系列的工作。
中间件的语法:
1 2 3 4 5 | function 中间的名字(req,res,next){ //req:代表的是http请求 //res:代表的是http 响应 //next:代表调用下一个中间件 } |
扩展内容
(1) npm i nodemon 是一个很好的全局工具,可以在每次修改内容后不用重新启动服务
(2) 浏览器输入的请求地址,都是默认为get请求方式
(3) 推荐使用postman软件
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现