破酥 | C4iN
express+vue前后端分离

express+vue前后端分离

本文介绍express和vue搭配的简单使用。

express

express安装

1
2
npm install -D express
npm install -D express-generatoe

创建express项目:

1
express <项目名称>

express项目结构

1
2
3
4
5
├─bin				# 服务器默认脚本,用于启动服务
├─node_modules # 依赖包
├─public # 静态文件
├─routes # 路由文件
└─views # 视图文件

app.js

app.js 文件相当于项目启动的主入口文件,有一些公共方法和服务器配置等信息:

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
47
48
49
50
// http错误处理模块
var createError = require('http-errors');
// 引入Express
var express = require('express');
// 引入path
var path = require('path');
// 引入cookie处理
var cookieParser = require('cookie-parser');
//引入日志模块
var logger = require('morgan');
// 引入路由目录中的index.js文件
var indexRouter = require('./routes/index');
// 引入路由目录中的users.js文件
var usersRouter = require('./routes/users');
// 创建Express应用
var app = express();
// 定义页面目录
app.set('views', path.join(__dirname, 'views'));
// 定义页面模板引擎
app.set('view engine', 'jade');
// 定义日志打印级别
app.use(logger('dev'));
// 定义JSON格式处理数据
app.use(express.json());
// 定义使用urlencode处理数据及querystring模块解析数据
app.use(express.urlencoded({ extended: false }));
// 定义cookie处理对象
app.use(cookieParser());
// 定义静态资源目录public
app.use(express.static(path.join(__dirname, 'public')));
// 定义指向index.js的路由
app.use('/', indexRouter);
// 定义指向users.js的路由
app.use('/users', usersRouter);
// 定义404错误处理
app.use(function(req, res, next) {
next(createError(404));
});
// 定义其他错误处理
app.use(function(err, req, res, next) {
// 设置locals,只在开发环境生效
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// 返回错误http状态码
res.status(err.status || 500);
// 渲染错误页面
res.render('error');
});

module.exports = app;

express接口

我们使用路由方法来创建接口,第一个参数 “/” 为路由地址,第二个参数为路由处理函数,是一个回调函数,该函数接受两个参数分别表示请求和响应。当路由方法和路由地址匹配到用户请求时,路由处理函数就会执行。

路由方法根据基本 API 规则支持五种,分别如下:

  • app.get():GET 请求。
  • app.post():POST 请求。
  • app.put():PUT 请求。
  • app.delete():DELETE 请求。
  • app.all():匹配所有请求。

GET 请求:用于请求数据,通常不携带消息体,数据通过 URL 参数传递。GET 请求的安全性较低,因为参数暴露在 URL 中。

POST 请求:用于发送数据,消息体中包含了用户提交的数据。相比 GET 请求,POST 适合传输敏感数据或较大的数据量。

对于每个接口,我们在routes文件夹中创建对应名称的js文件,比如/test对应test.js

1
2
3
4
5
6
var express = require('express');
var router = express.Router();

...

module.exports = router;

然后在 app.js 文件中添加:

1
2
var testRouter = require('./routes/test');
app.use('/test', testRouter);

get 请求

app.get() 接受两个参数:第一个参数是请求的路径,第二个参数是处理该请求的回调函数。GET 请求中通常会通过 URL 附带查询参数,这些参数可以通过 req.query 获取。

1
2
3
4
5
6
7
8
9
router.get('/', function (req, res) {
const query = req.query
//调用res.send()方法,把数据响应给客户端
res.send({
status: 200, // 状态
msg:'GET请求成功', // 状态描述
data: query // 需要响应给客户端的具体数据
})
})

除了查询参数,GET 请求还可以通过路径参数传递数据。路径参数是 URL 的一部分,可以通过 req.params 获取。例如,我们可以通过修改路径来获取用户名:

1
2
3
4
app.get('/user/:name', (req, res) => {
const name = req.params.name;
res.send(`Hello, ${name}`);
});

post 请求

POST 请求通常用于将数据提交给服务器。我们可以通过 app.post() 方法监听 POST 请求。以下是一个简单的示例,处理用户的注册信息。POST 请求的数据通常存放在请求体中,而不是通过 URL 传递。为了解析 POST 请求体中的数据,Express 需要借助 express.json()express.urlencoded() 中间件。

1
2
3
4
5
6
7
8
router.post('/', function (req, res) {
//获取到客户端通过查询字符串,发送到服务器的数据
res.send({
status:0, //状态,0表示成功,1表示失败
msg:'POST请求成功', //状态描述
data: req.body // 需要响应给客户端的具体数据
})
})

我们用 postman 进行测试:

如果客户端提交的数据是表单格式的(即 application/x-www-form-urlencoded),我们可以使用 express.urlencoded() 中间件来解析请求体。

1
2
3
4
5
6
7
8
9
10
app.use(express.urlencoded({ extended: true }));

router.post('/', function (req, res) {
//获取到客户端通过查询字符串,发送到服务器的数据
res.send({
status:0, //状态,0表示成功,1表示失败
msg:'POST请求成功', //状态描述
data: req.body // 需要响应给客户端的具体数据
})
})

express中间件

Express 中的中间件是请求处理流水线的一部分,它们在请求到达路由之前,或者在响应发送给客户端之前执行。中间件可以对请求进行处理、修改,或者终止请求。常见的中间件用途包括:

  • 解析请求体
  • 设置 CORS 头
  • 处理身份验证和授权

中间件可以全局应用于所有请求,或者仅针对特定路由应用,也可以将中间件限定在特定路由中使用。

1
2
3
4
5
6
7
8
// 全局使用
app.use(express.json());

// 特定路由
app.post('/register', express.json(), (req, res) => {
const { username, password } = req.body;
res.send(`User ${username} registered with password ${password}`);
});

Vue

由于前后端的地址可能不同,我们需要在vite.config.ts中配置跨源:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
export default defineConfig({

...

server: {
// port: 8888, // 指定开发服务器端口
open: true, // 在开发服务器启动时自动在浏览器中打开应用程序
proxy: {
'^/api/.*': {
target: 'http://localhost:8888/api', // 跨源目标
changeOrigin: true, // 允许跨域
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}

})

GET 请求

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
const data = ref(null);
const error = ref(null);
const loading = ref(true);

let user = {
name: 'John',
surname: 'Smith'
};

const fetchData = async () => {
try {
const response = await fetch("api/test");
data.value = await response.json();
console.log(data.value)

} catch (e: any) {
error.value = e.message;
} finally {
loading.value = false;
}
};

onMounted(() => {
fetchData();
});

由于我们无法直接使用Promise返回的数据,所以用resulterrorloading分别存储 Promise 的结果、错误信息和加载状态。

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
27
28
29
30
31
const data = ref(null);
const error = ref(null);
const loading = ref(true);

let user = {
name: 'John',
surname: 'Smith'
};

const fetchData = async () => {
try {
const response = await fetch("api/test", {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(user)
});
data.value = await response.json();
console.log(data.value)

} catch (e: any) {
error.value = e.message;
} finally {
loading.value = false;
}
};

onMounted(() => {
fetchData();
});

注意,发送 POST 请求时,如果请求的 body 是字符串,则 Content-Type 会默认设置为 text/plain;charset=UTF-8。但是,当我们要发送 JSON 时,我们会使用 headers 选项来发送 application/json,这是 JSON 编码的数据的正确的 Content-Type

axios

我们使用 Axios 进行发送请求和处理响应。它是基于 Promise 的,可以更方便地处理异步操作。

1
npm install -D axios

参考:

《Node.js+Express+Vue项目实战》– 1.安装和使用Express(笔记)-腾讯云开发者社区-腾讯云 (tencent.com)

【Node.js】Express—监听 GET 和 POST 请求及处理参数详解-CSDN博客

【Vue】深入了解 Axios 在 Vue 中的使用:从基本操作到高级用法的全面指南_vue如何使用axios详解-CSDN博客

vite官方中文文档-开发服务器选项

Author:破酥 | C4iN
Link:https://c4in1.github.io/2024/09/19/vue/express-vue前后端分离/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可