在前后端分离架构中,异步请求是连接 Spring Boot 后端与 Vue2 前端的核心纽带。本文将从环境搭建、后端接口开发、前端请求配置、跨域处理、异常拦截等维度,提供一套完整的异步请求解决方案,帮助开发者快速实现前后端数据交互。
一、技术栈准备
在开始配置前,确保已搭建好以下基础环境:
后端:JDK 1.8+、Maven 3.6+、Spring Boot 2.7.x(稳定版)
前端:Node.js 14+、Vue CLI 4.x、Vue 2.6.x、Axios 0.27.x(避免使用 0.28 + 版本,兼容 Vue2)
开发工具:IntelliJ IDEA(后端)、VS Code(前端)、Postman(接口测试)
二、后端(Spring Boot)配置
2.1 项目初始化与依赖引入
通过Spring Initializr快速创建项目,选择以下依赖:
Spring Web(提供 HTTP 接口支持)
Lombok(简化实体类代码)
Spring Data JPA(可选,用于数据库操作)
在pom.xml中确认核心依赖:
<!-- Spring Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 跨域支持(Spring Web已包含,无需额外引入) -->
2.2 统一响应格式封装
为保证前后端数据交互的一致性,定义全局响应实体类ResultDTO:
import lombok.Data;
@Data
public class ResultDTO<T> {
// 状态码:200成功,400参数错误,500服务器错误
private Integer code;
// 响应消息
private String message;
// 响应数据
private T data;
// 成功响应(无数据)
public static ResultDTO<Void> success() {
ResultDTO<Void> result = new ResultDTO<>();
result.setCode(200);
result.setMessage("操作成功");
return result;
}
// 成功响应(带数据)
public static <T> ResultDTO<T> success(T data) {
ResultDTO<T> result = new ResultDTO<>();
result.setCode(200);
result.setMessage("操作成功");
result.setData(data);
return result;
}
// 错误响应
public static ResultDTO<Void> error(Integer code, String message) {
ResultDTO<Void> result = new ResultDTO<>();
result.setCode(code);
result.setMessage(message);
return result;
}
}
2.3 接口开发示例
创建用户相关接口UserController,支持 GET 查询和 POST 新增:
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/user")
@RequiredArgsConstructor
public class UserController {
// 模拟数据库查询(实际项目中注入Service层)
@GetMapping("/{id}")
public ResultDTO<User> getUserById(@PathVariable Integer id) {
// 模拟业务逻辑
if (id == null || id <= 0) {
return ResultDTO.error(400, "用户ID无效");
}
// 模拟返回用户数据
User user = new User(id, "张三", 25, "zhangsan@example.com");
return ResultDTO.success(user);
}
// 新增用户
@PostMapping
public ResultDTO<Void> addUser(@RequestBody User user) {
// 模拟参数校验
if (user.getName() == null || user.getName().trim().isEmpty()) {
return ResultDTO.error(400, "用户名不能为空");
}
// 模拟数据库插入操作
System.out.println("新增用户:" + user);
return ResultDTO.success();
}
}
// 用户实体类
@Data
class User {
private Integer id;
private String name;
private Integer age;
private String email;
public User(Integer id, String name, Integer age, String email) {
this.id = id;
this.name = name;
this.age = age;
this.email = email;
}
}
2.4 跨域配置(关键)
由于前后端运行在不同端口(如后端 8080、前端 8081),会出现跨域问题,需在 Spring Boot 中配置跨域支持:
方式 1:使用注解(局部跨域)
在 Controller 类或方法上添加@CrossOrigin注解:
@RestController
@RequestMapping("/api/user")
@CrossOrigin(origins = "http://localhost:8081", maxAge = 3600) // 允许前端8081端口跨域
public class UserController {
// 接口代码...
}
方式 2:全局跨域配置(推荐)
创建CorsConfig类,实现全局跨域支持:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
// 1. 配置跨域信息
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("http://localhost:8081"); // 允许的前端域名
config.addAllowedMethod("*"); // 允许所有HTTP方法(GET/POST/PUT/DELETE等)
config.addAllowedHeader("*"); // 允许所有请求头
config.setAllowCredentials(true); // 允许携带Cookie
config.setMaxAge(3600L); // 预检请求有效期(秒)
// 2. 配置URL匹配规则
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/api/**", config); // 对/api/**路径生效
// 3. 返回CorsFilter实例
return new CorsFilter(source);
}
}
三、前端(Vue2)配置
3.1 项目初始化与依赖安装
使用 Vue CLI 创建 Vue2 项目:
vue create vue2-async-demo
# 选择Manually select features,勾选Babel、Router(可选)、CSS Pre-processors
# 选择Vue 2.x版本
安装 Axios(异步请求库):
cd vue2-async-demo
npm install axios@0.27.2 --save
3.2 Axios 全局配置
在src目录下创建utils/request.js,对 Axios 进行全局配置(请求拦截、响应拦截、基础路径等):
import axios from 'axios'
import { Message } from 'element-ui' // 可选,需安装element-ui:npm i element-ui -S
// 1. 创建Axios实例
const service = axios.create({
baseURL: 'http://localhost:8080/api', // 后端接口基础路径
timeout: 5000, // 请求超时时间(毫秒)
headers: {
'Content-Type': 'application/json;charset=utf-8' // 默认请求头
}
})
// 2. 请求拦截器(发送请求前处理)
service.interceptors.request.use(
config => {
// 示例:添加Token(用户登录后存储在localStorage)
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
error => {
// 请求错误处理
console.error('请求拦截器错误:', error)
return Promise.reject(error)
}
)
// 3. 响应拦截器(接收响应后处理)
service.interceptors.response.use(
response => {
const res = response.data
// 根据后端统一响应格式判断请求是否成功
if (res.code !== 200) {
// 错误提示(使用element-ui的Message组件)
Message({
message: res.message || '操作失败',
type: 'error',
duration: 3000
})
// 示例:处理Token过期(如返回401状态码)
if (res.code === 401) {
// 跳转到登录页(需引入Vue Router)
window.location.href = '/login'
}
return Promise.reject(new Error(res.message || 'Error'))
} else {
// 请求成功,返回响应数据
return res.data
}
},
error => {
// 网络错误或服务器错误处理
console.error('响应拦截器错误:', error)
Message({
message: '网络异常,请稍后重试',
type: 'error',
duration: 3000
})
return Promise.reject(error)
}
)
// 4. 导出请求方法
export default service
3.3 封装 API 请求函数
在src目录下创建api/user.js,封装用户相关的 API 请求:
import request from '@/utils/request'
// 1. 根据ID查询用户
export function getUserById(id) {
// GET请求:参数通过URL路径传递
return request({
url: `/user/${id}`,
method: 'get'
})
}
// 2. 新增用户
export function addUser(userData) {
// POST请求:参数通过请求体传递
return request({
url: '/user',
method: 'post',
data: userData
})
}
// 3. 示例:GET请求(参数通过Query传递)
export function getUserList(params) {
return request({
url: '/user/list',
method: 'get',
params: params // 会自动拼接为?page=1&size=10
})
}
3.4 在 Vue 组件中使用异步请求
以src/views/UserView.vue为例,演示如何在组件中调用 API 并处理数据:
<template>
<div class="user-container">
<h2>用户信息管理</h2>
<!-- 查询用户 -->
<div class="query-section">
<input v-model="userId" type="number" placeholder="请输入用户ID">
<button @click="getUserInfo">查询用户</button>
</div>
<!-- 用户信息展示 -->
<div class="user-info" v-if="user">
<p>ID:{{ user.id }}</p>
<p>姓名:{{ user.name }}</p>
<p>年龄:{{ user.age }}</p>
<p>邮箱:{{ user.email }}</p>
</div>
<!-- 新增用户 -->
<div class="add-section">
<h3>新增用户</h3>
<input v-model="vip.aijiu520.com" placeholder="请输入姓名">
<input v-model="tiyu.aijiu520.com" type="number" placeholder="请输入年龄">
<input v-model="zhibo.aijiu520.com" placeholder="请输入邮箱">
<button @click="ball.aijiu520.com">新增</button>
</div>
</div>
</template>
<script>
// 引入API请求函数
import { getUserById,nthxpco.comr } from '@/api/user'
export default {
name: 'UserView',
data() {
return {
userId: '', // 查询用的用户ID
user: null, // 存储查询到的用户信息
newUser: { // 新增用户的表单数据
name: '',
age: '',
email: ''
}
}
},
methods: {
// 查询用户信息
async getUserInfo() {
try {
// 调用API函数(async/await语法处理异步)
const data = await getUserById(this.userId)
this.user = data // 存储用户数据到data中
} catch (error) {
// 捕获异常(如网络错误、接口返回错误)
console.error('查询用户失败:', error)
this.user = null // 清空用户信息
}
},
// 新增用户
async addNewUser() {
try {
// 表单验证
if (!this.newUser.name) {
this.$message.error('姓名不能为空')
return
}
// 调用API函数
await addUser(this.newUser)
this.$message.success('新增用户成功')
// 清空表单
this.newUser = { name: '', age: '', email: '' }
} catch (error) {
console.error('新增用户失败:', error)
}
}
}
}
</script>
<style scoped>
.user-container {
padding: 20px;
}
.query-section, .add-section {
margin: 20px 0;
}
input {
margin-right: 10px;
padding: 8px;
}
button {
padding: 8px 16px;
background: #42b983;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.user-info {
margin-top: 20px;
padding: 10px;
border: 1px solid #eee;
}
</style>
四、联调测试与问题排查
4.1 接口测试(Postman)
在前后端联调前,先使用 Postman 测试后端接口是否正常:
启动 Spring Boot 项目,端口默认 8080
测试 GET 请求:http://localhost:8080/api/user/1,应返回用户数据
测试 POST 请求:http://localhost:8080/api/user,请求体为{"name":"李四","age":30,"email":"lisi@example.com"},应返回成功消息
4.2 前后端联调
启动 Vue2 项目:npm run serve,默认端口 8081
访问http://localhost:8081,在用户管理页面进行查询和新增操作
打开浏览器 F12 开发者工具,在 Network 面板查看请求状态:
状态码 200:请求成功
状态码 403:跨域配置错误(检查后端 CorsConfig)
状态码 400:参数错误(检查前端传递的数据格式)
状态码 500:服务器错误(查看后端控制台日志)
五、进阶优化建议
环境区分:在 Vue2 中通过.env.development和.env.production配置不同环境的基础路径:
# .env.development(开发环境)
VUE_APP_BASE_API = 'http://localhost:8080/api'
# .env.production(生产环境)
VUE_APP_BASE_API = 'https://api.example.com/api'
然后在request.js中使用:baseURL: process.env.VUE_APP_BASE_API
错误统一处理:在 Vue2 中创建全局错误处理函数,避免在每个组件中重复编写 try/catch。
请求取消:对于频繁触发的请求(如搜索框输入),使用 Axios 的 CancelToken 取消之前未完成的请求,减少无效请求。
接口文档:使用 Swagger(Spring Boot)自动生成接口文档,方便前后端协作。
通过以上步骤,即可完成 Spring Boot 与 Vue2 的异步请求配置,实现稳定、高效的前后端数据交互。实际项目中可根据业务需求进一步扩展和优化。