【Node.js工程师养成计划】之express框架

一、Express

官网:http://www.expressjs.com.cn

express 是一个基于内置核心 http 模块的,一个第三方的包,专注于 web 服务器的构建。

Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。

使用 Express 可以快速地搭建一个完整功能的网站。

Express 框架核心特性:

  • 可以设置中间件来响应 HTTP 请求。

  • 定义了路由表用于执行不同的 HTTP 请求动作。

  • 可以通过向模板传递参数来动态渲染 HTML 页面。

Express适合做什么

  • 传统web网站
  • API接口服务器
  • 服务端渲染中间层
  • 开发辅助工具
  • 自定义集成框架

二、Express项目构建

npm init -y
npm install express --save
npx express-generator

使用 npx express-generator 命令可以自动创建一个包含所有基本目录和文件的 Express.js 应用模板,这样开发者就可以直接开始编写业务代码,而不需要从零开始设置项目结构。
这个生成的项目通常包括以下部分:

  • bin 目录:存放可执行文件,包括启动应用的脚本。
  • public 目录:用于存放静态文件,如图片、JavaScript 和 CSS 文件。
  • routes 目录:存放路由文件,定义应用的路由逻辑。
  • views 目录:存放视图文件,通常是模板文件,用于生成 HTML 响应。
  • app.js:应用的主入口文件,配置中间件、路由等。
    在这里插入图片描述

三、express框架的基本使用

// 引入express
const express = require('express')
// 创建应用对象
const app = express();app.get('/', function(req, res){// 响应消息内容res.send('全体起立!')
})// 监听服务
app.listen(4000, () => {console.log('run http://127.0.0.1:4000');
})

在这里插入图片描述
request 和 response 对象的具体介绍:

Request 对象 - request 对象表示 HTTP 请求,包含了请求查询字符串,参数,内容,HTTP 头部等属性。常见属性有:

req.app:当callback为外部文件时,用req.app访问express的实例
req.baseUrl:获取路由当前安装的URL路径
req.body / req.cookies:获得「请求主体」/ Cookies
req.fresh / req.stale:判断请求是否还「新鲜」
req.hostname / req.ip:获取主机名和IP地址
req.originalUrl:获取原始请求URL
req.params:获取路由的parameters
req.path:获取请求路径
req.protocol:获取协议类型
req.query:获取URL的查询参数串
req.route:获取当前匹配的路由
req.subdomains:获取子域名
req.accepts():检查可接受的请求的文档类型
req.acceptsCharsets / req.acceptsEncodings / req.acceptsLanguages:返回指定字符集的第一个可接受字符编码
req.get():获取指定的HTTP请求头
req.is():判断请求头Content-Type的MIME类型

Response 对象 - response 对象表示 HTTP 响应,即在接收到请求时向客户端发送的 HTTP 响应数据。常见属性有:

res.app:同req.app一样
res.append():追加指定HTTP头
res.set()在res.append()后将重置之前设置的头
res.cookie(name,value [,option]):设置Cookie
opition: domain / expires / httpOnly / maxAge / path / secure / signed
res.clearCookie():清除Cookie
res.download():传送指定路径的文件
res.get():返回指定的HTTP头
res.json():传送JSON响应
res.jsonp():传送JSONP响应
res.location():只设置响应的Location HTTP头,不设置状态码或者close response
res.redirect():设置响应的Location HTTP头,并且设置状态码302
res.render(view,[locals],callback):渲染一个view,同时向callback传递渲染后的字符串,如果在渲染过程中有错误发生next(err)将会被自动调用。callback将会被传入一个可能发生的错误以及渲染后的页面,这样就不会自动输出了。
res.send():传送HTTP响应
res.sendFile(path [,options] [,fn]):传送指定路径的文件 -会自动根据文件extension设定Content-Type
res.set():设置HTTP头,传入object可以一次设置多个头
res.status():设置HTTP状态码
res.type():设置Content-Type的MIME类型

四、Express管理用户数据信息

项目目录:
在这里插入图片描述
db.json

{"users": [{"id": 1,"username": "Monica","age": "22"},{"id": 2,"username": "Alen","age": "26"}],"video": []
}
// 引入express
const express = require('express')
const fs = require('fs');
const { json } = require('stream/consumers');
// 创建应用对象
const app = express();app.get('/', function(req, res){fs.readFile('./db.json', 'utf-8',(err, data) => {if (!err) {const back = JSON.parse(data)res.send(back.users)} else {res.status(500).json({err})}})
})// 监听服务
app.listen(4000, () => {console.log('run http://127.0.0.1:4000');
})

在这里插入图片描述
在这里插入图片描述
可以使用apifox去管理接口
在这里插入图片描述
解决回调地狱问题:

// 引入express
const express = require('express')
const fs = require('fs');
const { promisify } = require('util')
const readFile = promisify(fs.readFile)// 创建应用对象
const app = express();app.get('/', async function(req, res){try {let back = await readFile('./db.json', 'utf-8')res.send(JSON.parse(back))} catch (err) {res.status(500).json({err})}
})// 监听服务
app.listen(4000, () => {console.log('run http://127.0.0.1:4000');
})

五、处理客户端Post请求数据

// 引入express
const express = require('express')
const fs = require('fs');
const { promisify } = require('util')
const readFile = promisify(fs.readFile)// 创建应用对象
const app = express();
// app.use(express.urlencoded())
app.use(express.json())app.get('/', async function(req, res){try {let back = await readFile('./db.json', 'utf-8')res.send(JSON.parse(back))} catch (err) {res.status(500).json({err})}
})app.post('/', async (req, res) => {console.log(req.headers)console.log(req.body)
})// 监听服务
app.listen(4000, () => {console.log('run http://127.0.0.1:4000');
})

在这里插入图片描述
app.use(express.urlencoded()) 是 Express 框架中的一个中间件,用于解析来自客户端的 URL 编码的请求体数据,并将其转换为 JavaScript 对象。这通常用于处理 POST 请求中的表单数据。使用这个中间件后,你可以在路由处理程序中通过 req.body 来访问表单数据。
app.use(express.json()) 来解析 JSON 格式的请求体数据

六、添加用户信息到db文件

拿到提交的表单值:

// 引入express
const express = require('express')
const fs = require('fs');
const { promisify } = require('util')
const readFile = promisify(fs.readFile)// 创建应用对象
const app = express();
// app.use(express.urlencoded())
app.use(express.json())app.get('/', async function(req, res){try {let back = await readFile('./db.json', 'utf-8')res.send(JSON.parse(back))} catch (err) {res.status(500).json({err})}
})app.post('/', async (req, res) => {console.log(req.headers)// console.log(req.body)let body = req.bodyif (!body) {res.status(403).json({err: '缺少用户信息'})}let back = await readFile('./db.json', 'utf-8')const jsonObj = JSON.parse(back)// 给输入的用户信息添加个idbody.id = jsonObj.users[jsonObj.users.length-1].id + 1jsonObj.users.push(body)console.log(body);res.send(body)
})// 监听服务
app.listen(4000, () => {console.log('run http://127.0.0.1:4000');
})

文件写入:

// 引入express
const express = require('express')
const fs = require('fs');
const { promisify } = require('util')
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)// 创建应用对象
const app = express();
// app.use(express.urlencoded())
app.use(express.json())app.get('/', async function(req, res){try {let back = await readFile('./db.json', 'utf-8')res.send(JSON.parse(back))} catch (err) {res.status(500).json({err})}
})app.post('/', async (req, res) => {console.log(req.headers)// console.log(req.body)let body = req.bodyif (!body) {res.status(403).json({err: '缺少用户信息'})}let back = await readFile('./db.json', 'utf-8')const jsonObj = JSON.parse(back)// 给输入的用户信息添加个idbody.id = jsonObj.users[jsonObj.users.length-1].id + 1jsonObj.users.push(body)// 写入文件try{let w = await writeFile('./db.json', JSON.stringify(jsonObj))if(!w){res.status(200).send({msg: '添加成功'})}} catch(err){res.status(500).json({err})}
})// 监听服务
app.listen(4000, () => {console.log('run http://127.0.0.1:4000');
})

在这里插入图片描述
逻辑抽离:
db.js

const { promisify } = require('util')
const fs = require('fs')
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)exports.getDb = async () => {let data = await readFile('./db.json', 'utf-8')return JSON.parse(data)
}exports.serveDb = async (data) => {return await writeFile('./db.json', JSON.stringify(data))
}

app.js

// 引入express
const express = require('express')
const db = require('./db')// 创建应用对象
const app = express();
// app.use(express.urlencoded())
app.use(express.json())app.get('/', async function(req, res){try {let back = await db.getDb()res.send(back)} catch (err) {res.status(500).json({err})}
})app.post('/', async (req, res) => {// console.log(req.headers)// console.log(req.body)let body = req.bodyif (!body) {res.status(403).json({err: '缺少用户信息'})}let back = await db.getDb()const jsonObj = back// 给输入的用户信息添加个idbody.id = jsonObj.users[jsonObj.users.length-1].id + 1jsonObj.users.push(body)// 写入文件try{let w = await db.serveDb(jsonObj)console.log(111, w)if(!w){res.status(200).send({msg: '添加成功'})}} catch(err){res.status(500).json({err})}
})// 监听服务
app.listen(4000, () => {console.log('run http://127.0.0.1:4000');
})

七、修改用户信息

// 引入express
const express = require('express')
const db = require('./db')// 创建应用对象
const app = express();
// app.use(express.urlencoded())
app.use(express.json())app.get('/', async function(req, res){try {let back = await db.getDb()res.send(back)} catch (err) {res.status(500).json({err})}
})app.post('/', async (req, res) => {// console.log(req.headers)// console.log(req.body)let body = req.bodyif (!body) {res.status(403).json({err: '缺少用户信息'})}let back = await db.getDb()const jsonObj = back// 给输入的用户信息添加个idbody.id = jsonObj.users[jsonObj.users.length-1].id + 1jsonObj.users.push(body)// 写入文件try{let w = await db.serveDb(jsonObj)if(!w){res.status(200).send({msg: '添加成功'})}} catch(err){res.status(500).json({err})}
})app.put('/:id', async (req, res) => {// console.log(req.params.id) // 传进来的数据// console.log(req.body)try{let userInfo = await db.getDb()let userId = Number(req.params.id)let user = userInfo.users.find(item => item.id === userId)if (!user){res.status(403).send({msg: '用户不存在'})}const body = req.bodyuser.username = body.username ? body.username : user.usernameuser.age = body.age ? body.age : user.ageuserInfo.users[userId - 1] = userlet w = await db.serveDb(userInfo)if (!w) {res.status(201).send({msg: '修改成功'})}} catch(err){res.status(500).json({err})}
})// 监听服务
app.listen(4000, () => {console.log('run http://127.0.0.1:4000');
})

在这里插入图片描述
在这里插入图片描述

八、学到这里,感觉nodeJS还挺有意思的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/318786.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络安全知识点

网络安全 1. 网络安全的定义,网络安全的属性。 定义:针对各种网络安全威胁研究其安全策略和机制,通过防护、检测和响应,确保网络系统及数据的安全性。 属性:机密性 认证(可鉴别性&#xff09…

【Leetcode每日一题】 分治 - 排序数组(难度⭐⭐)(69)

1. 题目解析 题目链接:912. 排序数组 这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。 2.算法原理 归并排序(Merge Sort)是一种采用“分而治之”(Divide and Conquer)策略…

解决RTC内核驱动的问题bm8563

常用pcf-8563 , 国产平替BM8563(驱动管脚一致); 实时时钟是很常用的一个外设,通过实时时钟我们就可以知道年、月、日和时间等信息。 因此在需要记录时间的场合就需要实时时钟,可以使用专用的实时时钟芯片来完成此功能 RTC 设备驱动是一个标准…

【webrtc】MessageHandler 4: 基于线程的消息处理:以Fake 收发包模拟为例

G:\CDN\rtcCli\m98\src\media\base\fake_network_interface.h// Fake NetworkInterface that sends/receives RTP/RTCP packets.虚假的网络接口,用于模拟发送包、接收包单纯仅是处理一个ST_RTP包 消息的id就是ST_RTP 类型,– 然后给到目的地:mediachannel处理: 最后消息消…

rust前端web开发框架yew使用

构建完整基于 rust 的 web 应用,使用yew框架 trunk 构建、打包、发布 wasm web 应用 安装后会作为一个系统命令,默认有两个特性开启 rustls - 客户端与服务端通信的 tls 库update_check - 用于应用启动时启动更新检查,应用有更新时提示用户更新。nati…

【LeetCode刷题】410. 分割数组的最大值

1. 题目链接2. 题目描述3. 解题方法4. 代码 1. 题目链接 410. 分割数组的最大值 2. 题目描述 3. 解题方法 题目中提到的是某个和的最大值是最小的,这种题目是可以用二分来解决的。 确定区间,根据题目的数据范围,可以确定区间就是[0, 1e9]…

【华为 ICT HCIA eNSP 习题汇总】——题目集20

1、(多选)若两个虚拟机能够互相ping通,则通讯过程中会使用()。 A、虚拟网卡 B、物理网卡 C、物理交换机 D、分布式虚拟交换机 考点:数据通信 解析:(AD) 物理网卡是硬件设…

基于SSM SpringBoot vue宾馆网上预订综合业务服务系统

基于SSM SpringBoot vue宾馆网上预订综合业务服务系统 系统功能 首页 图片轮播 宾馆信息 饮食美食 休闲娱乐 新闻资讯 论坛 留言板 登录注册 个人中心 后台管理 登录注册 个人中心 用户管理 客房登记管理 客房调整管理 休闲娱乐管理 类型信息管理 论坛管理 系统管理 新闻资讯…

记录一下安装cv2的过程

python安装cv2库(命令行安装法,每一步都可复制命令,非常贴心!),手把手安装-CSDN博客 主要是参考的这篇文章 pip install opencv-python关键命令就是这一行,会比较慢 加上清华源吧

Mybatis.net + Mysql

项目文件结构 NuGet下载Mybatis.net相关包:IBatisNet 安装完成后,会显示在,在已安装页面。同时,在管理器中的引用列表中,会多出来两个引用文件 IBatisNet.CommonIBatisNet.DataMapper 安装 Mysql.data。 注意&#xff…

AJ-Report开源数据大屏 verification;swagger-ui RCE漏洞复现

0x01 产品简介 AJ-Report是一个完全开源的BI平台,酷炫大屏展示,能随时随地掌控业务动态,让每个决策都有数据支撑。多数据源支持,内置mysql、elasticsearch、kudu等多种驱动,支持自定义数据集省去数据接口开发,支持17+种大屏组件,不会开发,照着设计稿也可以制作大屏。三…

亚马逊云科技AWS免费证书-EC2服务器设计(含题库)

亚马逊云AWS官方程序员专属免费证书又来了!这次证书是关于AWS EC2实例的设计和搭建,EC2作为AWS服务的核心,是学好AWS的第一步。强推没有任何AWS背景和转码的小伙伴去学!学完也能变成AWS开发大神! 证书名字叫Getting St…

Excel 中用于在一个范围中查找特定的值,并返回同一行中指定列的值 顺序不一样 可以处理吗

一、需求 Excel 中,在一列(某范围内)查找另一列特定的值,并返回同一行中另一指定列的值, 查找列和返回列的顺序不一样 二、 实现 1、下面是一个使用 INDEX 和 MATCH 函数的例子: 假设你有以下数据&…

领域驱动设计(DDD)笔记(三)后端工程架构

文章链接 领域驱动设计(DDD)笔记(一)基本概念-CSDN博客领域驱动设计(DDD)笔记(二)代码组织原则-CSDN博客领域驱动设计(DDD)笔记(三)后端工程架构-CSDN博客前导 领域驱动设计(Domain Driven Design,简称DDD)是业内主导的业务工程理论。它在各中权威人士被广泛讨论…

【ZYNQ】Zynq 开发流程

Zynq 芯片架构由嵌入式处理器(Processing System, PS)与可编程逻辑(Programmable Logic, PL),以及 PS 与 PL 之间的互联总线组成。本文主要介绍 Xilinx Zynq 芯片开发所使用的软件,包括 Vivado IDE 与 Xili…

ASP.NET网络在线考试系统

摘 要 随着计算机技术的发展和互联网时代的到来,人们已经进入了信息时代,也有人称为数字化时代。数在数字化的网络环境下,学生希望得到个性化的满足,根据自己的情况进行学习,同时也希望能够得到科学的评价&#xff0c…

分布式事务—> seata

分布式事务之Seata 一、什么是分布式事务? 分布式事务是一种特殊类型的事务,它涉及多个分布式系统中的节点,包括事务的参与者、支持事务的服务器、资源服务器以及事务管理器。 在分布式事务中,一次大型操作通常由多个小操作组成…

无人机+无人车:自组网协同技术及应用前景详解

无人车,也被称为自动驾驶汽车、电脑驾驶汽车或轮式移动机器人,是一种通过电脑系统实现无人驾驶的智能汽车。这种汽车依靠人工智能、视觉计算、雷达、监控装置和全球定位系统协同合作,使得电脑可以在没有任何人类主动操作的情况下,…

手撕vector的模拟实现

𝙉𝙞𝙘𝙚!!👏🏻‧✧̣̥̇‧✦👏🏻‧✧̣̥̇‧✦ 👏🏻‧✧̣̥̇:Solitary_walk ⸝⋆ ━━━┓ - 个性标签 - :来于“云”的“羽球人”。…

华为云耀云服务器开放端口

博客主页:花果山~程序猿-CSDN博客 关注我一起学习,一起进步,一起探索编程的无限可能吧!让我们一起努力,一起成长! 目录 一.华为云控制台开放端口 寻找到安全组信息 2. 添加开放的端口信息 3. 检查是否成…