Node.js-4-express&cors&mysql

node.js-4

Express中间件

1
2
3
4
5
6
app.post('/user', (req, res) => {
// 在服务器,可以使用 req.body 这个属性,来接收客户端发送过来的请求体数据
// 默认情况下,如果不配置解析表单数据的中间件,则 req.body 默认等于 undefined
console.log(req.body)
res.send('ok')
})

自定义中间件

自己手动模拟一个类似于express.urlencoded这样的中间件,来解析 POST 提交到服务器的表单数据。

实现步骤:

①定义中间件

②监听 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
// 导入 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

qs.parse是把字符串转换成对象

编写接口

基于cors解决接口跨域问题

cors是Express的一个第三方中间件。通过安装和配置cors中间件,可以很方便地解决跨域问题。

使用步骤分为如下3步:

①运行 npm install cors 安装中间件

②使用 const cors = require(‘cors’) 导入中间件

③在路由之前调用 app.use(cors()) 配置中间件

什么是cors

CORS(Cross-OriginResource Sharing,跨域资源共享)由一系列 HTTP 响应头组成,这些 HTTP 响应头决定浏览器是否阻止前端 JS 代码跨域获取资源。

浏览器的同源安全策略默认会阻止网页“跨域”获取资源。但如果接口服务器配置了 CORS 相关的 HTTP 响应头,就可以解除浏览器端的跨域访问限制。

①CORS 主要在服务器端进行配置。客户端浏览器无须做任何额外的配置,即可请求开启了 CORS的接口。

②CORS 在浏览器中有兼容性。只有支持XMLHttpRequestLevel2 的浏览器,才能正常访问开启了CORS的服务端接口(例如:IE10+、Chrome4+、FireFox3.5+)。

CORS响应头部

Access-Control-Allow-Origin

Access-Control-Allow-Headers

Access-Control-Allow-Methods

请求的分类

客户端在请求CORS接口时,根据请求方式和请求头的不同,可以将CORS的请求分为两大类,分别是:

简单请求

同时满足以下两大条件的请求,就属于简单请求:

① 请求方式:GET、POST、HEAD三者之一

② HTTP 头部信息不超过以下几种字段:无自定义头部字段、Accept、Accept-Language、Content-Language、DPR、Downlink、Save-Data、Viewport-Width、Width、Content-Type(只有三个值application/x-www-form-urlencoded、multipart/form-data、text/plain)

预检请求

只要符合以下任何一个条件的请求,都需要进行预检请求:

① 请求方式为 GET、POST、HEAD 之外的请求 Method 类型

② 请求头中包含自定义头部字段

③ 向服务器发送了 application/json 格式的数据

在浏览器与服务器正式通信之前,浏览器会先发送 OPTION 请求进行预检,以获知服务器是否允许该实际请求,所以这一次的 OPTION请求称为“预检请求”。服务器成功响应预检请求后,才会发送真正的请求,并且携带真实数据。

基于JSONP(在前面Ajax笔记中有提到)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
JSONP(JSON with Padding)是一种使用<script>元素进行跨域请求的方法,它可以绕过同源策略的限制。JSONP通过在页面中动态创建<script>元素,将需要请求的数据封装在一个回调函数中,然后将该回调函数的名称作为参数传递给服务器。

以下是JSONP的工作原理步骤:

1.在页面中创建一个<script>元素,并将其src属性设置为目标服务器上的URL。该URL包含需要请求的数据以及回调函数的名称作为参数。

2.目标服务器接收到请求后,解析URL参数中的回调函数名称,并将需要返回的数据作为参数传递给该回调函数。

3.目标服务器返回的响应是一个JavaScript函数调用,该函数调用会执行在页面中事先定义好的回调函数。

4.在页面中定义的回调函数会在响应返回时被调用,从而可以在函数内部处理返回的数据。

由于<script>元素的src属性不受同源策略的限制,因此可以从任何域加载脚本。这样就允许你通过在目标服务器上动态生成包装了数据的JavaScript代码,并在浏览器中执行。

需要注意的是,JSONP存在一些安全风险,因为它要求你信任目标服务器上返回的代码。恶意的服务器可能会返回恶意代码,导致安全问题。因此,在使用JSONP时,你应该确保只向可信任的服务器发出请求,并仔细验证返回的数据。另外,由于JSONP只支持GET请求,不支持POST等其他类型的请求。

在项目中操作MySQL

①安装操作 MySQL数据库的第三方模块(mysql)

②通过 mysql模块连接到 MySQL 数据库

③通过 mysql模块执行 SQL 语句

安装MySQL模块

mysql模块是托管于npm上的第三方模块。它提供了在Node.js项目中连接和操作MySQL数据库的能力

1
npm install mysql

配置 mysql 模块

在使用 mysql模块操作MySQL数据库之前,必须先对 mysql 模块进行必要的配置,主要的配置步骤如下

1
2
3
4
5
6
7
8
9
// 1. 导入 mysql 模块
const mysql = require('mysql')
// 2. 建立与 MySQL 数据库的连接关系
const db = mysql.createPool({
host: '127.0.0.1', // 数据库的 IP 地址
user: 'root', // 登录数据库的账号
password: 'admin123', // 登录数据库的密码
database: 'm_db_01', // 指定要操作哪个数据库
})

测试mysql 模块能否正常工作

调用db.query()函数,指定要执行的SQL语句,通过回调函数拿到执行的结果:

相关操作

1
2
3
4
5
6
7
8
9
// 查询 users 表中所有的数据
const sqlStr = 'select * from users'
db.query(sqlStr, (err, results) => {
// 查询数据失败
if (err) return console.log(err.message)
// 查询数据成功
// 注意:如果执行的是 select 查询语句,则执行的结果是数组
console.log(results)
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 向 users 表中,新增一条数据,其中 username 的值为 Spider-Man,password 的值为 pcc123
/const user = { username: 'Spider-Man', password: 'pcc123' }
// 定义待执行的 SQL 语句
const sqlStr = 'insert into users (username, password) values (?, ?)'
// 执行 SQL 语句
db.query(sqlStr, [user.username, user.password], (err, results) => {
// 执行 SQL 语句失败了
if (err) return console.log(err.message)
// 成功了
// 注意:如果执行的是 insert into 插入语句,则 results 是一个对象
// 可以通过 affectedRows 属性,来判断是否插入数据成功
if (results.affectedRows === 1) {
console.log('插入数据成功!')
}
})
1
2
3
4
5
6
7
8
9
10
11
12
// 演示插入数据的便捷方式
const user = { username: 'Spider-Man2', password: 'pcc4321' }
// 定义待执行的 SQL 语句
const sqlStr = 'insert into users set ?'
// 执行 SQL 语句
db.query(sqlStr, user, (err, results) => {
if (err) return console.log(err.message)
if (results.affectedRows === 1) {
console.log('插入数据成功')
}
})

1
2
3
4
5
6
7
8
9
10
11
12
// 演示如何更新用户的信息
const user = { id: 6, username: 'aaa', password: '000' }
// 定义 SQL 语句
const sqlStr = 'update users set username=?, password=? where id=?'
// 执行 SQL 语句
db.query(sqlStr, [user.username, user.password, user.id], (err, results) => {
if (err) return console.log(err.message)
// 注意:执行了 update 语句之后,执行的结果,也是一个对象,可以通过 affectedRows 判断是否更新成功
if (results.affectedRows === 1) {
console.log('更新成功')
}
})
1
2
3
4
5
6
7
8
9
10
11
// 演示更新数据的便捷方式
const user = { id: 6, username: 'aaaa', password: '0000' }
// 定义 SQL 语句
const sqlStr = 'update users set ? where id=?'
// 执行 SQL 语句
db.query(sqlStr, [user, user.id], (err, results) => {
if (err) return console.log(err.message)
if (results.affectedRows === 1) {
console.log('更新数据成功')
}
})
1
2
3
4
5
6
7
8
9
// 删除 id 为 5 的用户
const sqlStr = 'delete from users where id=?'
db.query(sqlStr, 5, (err, results) => {
if (err) return console.log(err.message)
// 注意:执行 delete 语句之后,结果也是一个对象,也会包含 affectedRows 属性
if (results.affectedRows === 1) {
console.log('删除数据成功')
}
})

Node.js-4-express&cors&mysql
https://wjcbolg.cn/2023/06/03/node.js-4/
作者
JasonWang
发布于
2023年6月3日
许可协议
BY-JW