基于前端vue项目详细说说如何和后端联调接口?
以一个典型 Vue 前端项目 为例,详细说明前端如何和后端进行接口联调。内容会覆盖:环境配置、接口封装、代理跨域、请求调试、登录鉴权、联调流程、常见问题等。
一、前后端联调前需要先确认什么?
在开始联调接口之前,前端和后端需要先对齐以下内容。
1. 接口文档
通常后端会提供接口文档,例如:
- Swagger / Knife4j
- Apifox
- Postman 文档
- YApi
- Markdown / Wiki 文档
前端需要重点确认:
接口地址:/api/user/list
请求方式:GET / POST / PUT / DELETE
请求参数:query / params / body
请求头:Content-Type、Authorization
响应结构:code、data、message
错误码:401、403、500 等
例如:
{
"code": 200,
"message": "success",
"data": {
"list": [],
"total": 0
}
}
2. 后端服务地址
需要知道后端本地或测试环境地址,例如:
http://localhost:8080
http://192.168.1.100:8080
https://test-api.xxx.com
前端开发环境一般不会直接写死完整地址,而是通过代理或环境变量配置。
3. 是否需要登录鉴权
确认接口是否需要:
- token
- cookie
- session
- Authorization 请求头
- refresh token
- csrf token
例如:
Authorization: Bearer xxxxxx
二、Vue 项目中如何配置后端接口地址?
Vue 项目常见有两类:
- Vue CLI 创建的项目
- Vite 创建的 Vue 项目
现在新项目大多使用 Vite,下面两种都说一下。
三、Vite + Vue 项目接口联调配置
1. 配置环境变量
在项目根目录下创建:
.env.development
.env.production
.env.test
例如 .env.development:
VITE_API_BASE_URL=/api
.env.production:
VITE_API_BASE_URL=https://api.xxx.com
在代码中使用:
const baseURL = import.meta.env.VITE_API_BASE_URL
注意:Vite 环境变量必须以 VITE_ 开头。
2. 配置开发代理
在 vite.config.js 或 vite.config.ts 中配置:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
server: {
host: '0.0.0.0',
port: 5173,
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
}
}
}
})
含义:
前端请求:/api/user/list
实际转发:http://localhost:8080/user/list
如果后端接口本身就带 /api 前缀,比如:
http://localhost:8080/api/user/list
那就不要 rewrite:
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true
}
}
四、Vue CLI 项目接口联调配置
如果是 Vue CLI 项目,在 vue.config.js 中配置:
module.exports = {
devServer: {
port: 8081,
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
}
}
前端请求:
axios.get('/api/user/list')
实际转发到:
http://localhost:8080/user/list
五、封装 axios 请求
实际项目中不建议每个页面直接写 axios.get(),通常会统一封装。
1. 安装 axios
npm install axios
或者:
yarn add axios
2. 创建 request 实例
例如目录结构:
src
├─ api
│ ├─ user.js
│ └─ login.js
├─ utils
│ └─ request.js
├─ views
└─ main.js
创建 src/utils/request.js:
import axios from 'axios'
import router from '@/router'
const service = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL,
timeout: 10000
})
// 请求拦截器
service.interceptors.request.use(
config => {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
error => {
return Promise.reject(error)
}
)
// 响应拦截器
service.interceptors.response.use(
response => {
const res = response.data
if (res.code !== 200) {
console.error(res.message || '接口请求失败')
return Promise.reject(res)
}
return res.data
},
error => {
if (error.response) {
const status = error.response.status
if (status === 401) {
localStorage.removeItem('token')
router.push('/login')
}
}
return Promise.reject(error)
}
)
export default service
这样页面中就不用重复处理 token、错误码等逻辑。
六、按模块管理接口
例如 src/api/user.js:
import request from '@/utils/request'
export function getUserList(params) {
return request({
url: '/user/list',
method: 'get',
params
})
}
export function getUserDetail(id) {
return request({
url: `/user/${id}`,
method: 'get'
})
}
export function createUser(data) {
return request({
url: '/user/create',
method: 'post',
data
})
}
export function updateUser(data) {
return request({
url: '/user/update',
method: 'put',
data
})
}
export function deleteUser(id) {
return request({
url: `/user/${id}`,
method: 'delete'
})
}
页面中使用:
<script setup>
import { ref, onMounted } from 'vue'
import { getUserList } from '@/api/user'
const list = ref([])
const loading = ref(false)
const fetchUserList = async () => {
loading.value = true
try {
const data = await getUserList({
pageNum: 1,
pageSize: 10
})
list.value = data.list
} catch (error) {
console.error('获取用户列表失败', error)
} finally {
loading.value = false
}
}
onMounted(() => {
fetchUserList()
})
</script>
七、GET、POST 参数如何传?
1. GET 请求传 query 参数
接口:
GET /user/list?pageNum=1&pageSize=10
前端:
request({
url: '/user/list',
method: 'get',
params: {
pageNum: 1,
pageSize: 10
}
})
axios 中:
params会拼接到 URL 后面- 适用于 GET、DELETE 等请求
2. POST 请求传 JSON body
接口:
POST /user/create
Content-Type: application/json
前端:
request({
url: '/user/create',
method: 'post',
data: {
username: '张三',
age: 18
}
})
axios 中:
data是请求体- 常用于 POST、PUT、PATCH
3. 表单格式 application/x-www-form-urlencoded
如果后端要求表单格式:
import qs from 'qs'
request({
url: '/login',
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: qs.stringify({
username: 'admin',
password: '123456'
})
})
安装:
npm install qs
4. 上传文件 multipart/form-data
const formData = new FormData()
formData.append('file', file)
request({
url: '/upload',
method: 'post',
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
}
})
八、登录接口如何联调?
常见登录流程:
- 用户输入账号密码
- 调用登录接口
- 后端返回 token
- 前端保存 token
- 后续请求自动带上 token
- token 失效跳转登录页
接口:
POST /login
响应:
{
"code": 200,
"message": "success",
"data": {
"token": "xxxxxx"
}
}
前端代码:
import request from '@/utils/request'
export function login(data) {
return request({
url: '/login',
method: 'post',
data
})
}
页面:
const handleLogin = async () => {
try {
const data = await login({
username: form.username,
password: form.password
})
localStorage.setItem('token', data.token)
router.push('/home')
} catch (error) {
console.error('登录失败', error)
}
}
请求拦截器自动添加:
config.headers.Authorization = `Bearer ${token}`
如果后端要求的是:
token: xxxxxx
那就写:
config.headers.token = token
这个要和后端约定清楚。
九、如何解决跨域问题?
前端本地一般是:
http://localhost:5173
后端可能是:
http://localhost:8080
协议、域名、端口任一不同,就会产生跨域。
方案一:前端开发代理
开发环境推荐使用代理:
server: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
}
}
}
这是开发环境最常用方式。
方案二:后端开启 CORS
后端响应头设置:
Access-Control-Allow-Origin: http://localhost:5173
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS
Access-Control-Allow-Headers: Content-Type,Authorization
如果涉及 cookie,还需要:
Access-Control-Allow-Credentials: true
前端 axios:
axios.defaults.withCredentials = true
注意:使用 credentials 时,后端不能设置:
Access-Control-Allow-Origin: *
十、如何判断接口有没有真正调通?
可以从浏览器开发者工具看。
1. 打开 Network 面板
Chrome 浏览器:
F12 -> Network -> Fetch/XHR
查看:
- Request URL
- Request Method
- Status Code
- Request Headers
- Request Payload
- Response
2. 重点检查 Request URL
例如前端发起:
http://localhost:5173/api/user/list
通过代理后,实际后端收到:
http://localhost:8080/user/list
如果浏览器 Network 里看到 404,要确认:
- 前端接口路径是否写错
- 代理 rewrite 是否写错
- 后端接口是否有前缀
- 请求方式 GET/POST 是否正确
3. 查看请求参数
GET 参数看:
Query String Parameters
POST JSON 参数看:
Request Payload
表单参数看:
Form Data
4. 查看响应数据
Response 中确认:
{
"code": 200,
"data": {},
"message": "success"
}
如果接口返回成功,但页面不显示,通常是前端取值路径不对。
例如返回:
{
"code": 200,
"data": {
"records": [],
"total": 0
}
}
但前端写的是:
list.value = data.list
这就会显示为空,应该改为:
list.value = data.records
十一、联调接口的推荐流程
一个比较规范的联调流程如下:
第一步:后端先用接口工具自测
后端先在 Swagger、Postman、Apifox 中测试接口是否正常。
确认:
- 接口能访问
- 参数正确
- 响应结构稳定
- 错误码符合约定
第二步:前端用接口工具测试
前端也可以先用 Apifox/Postman 调接口。
目的:
- 排除前端代码问题
- 确认接口文档是否准确
- 确认 token、参数、响应字段
第三步:前端配置代理
例如:
proxy: {
'/api': {
target: 'http://后端地址:端口',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
}
}
配置完需要重启前端服务:
npm run dev
注意:修改 vite.config.js 后必须重启。
第四步:封装 API 方法
export function getUserList(params) {
return request({
url: '/user/list',
method: 'get',
params
})
}
第五步:页面调用接口
const data = await getUserList({ pageNum: 1, pageSize: 10 })
第六步:根据 Network 排查问题
重点看:
- URL 对不对
- method 对不对
- headers 对不对
- 参数对不对
- response 对不对
- status code 是多少
十二、常见联调问题和解决办法
1. 404 Not Found
可能原因:
- 接口地址写错
- 前端多写或少写
/api - 代理 rewrite 配置错误
- 后端接口路径和文档不一致
- 请求方式错误,比如接口是 POST,前端用了 GET
解决:
// 如果后端接口是 http://localhost:8080/api/user/list
// 前端请求 /api/user/list
// proxy 不要 rewrite
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true
}
}
2. 401 Unauthorized
可能原因:
- 没传 token
- token 过期
- token 格式不对
- 请求头字段名不对
检查:
Authorization: Bearer token
还是:
token: token
需要和后端约定。
3. 403 Forbidden
可能原因:
- 用户没有权限
- 后端权限配置限制
- csrf 校验失败
- token 有效但权限不足
4. 500 Internal Server Error
通常是后端代码异常。
前端需要提供给后端:
- 请求 URL
- 请求方法
- 请求参数
- 请求头
- 报错时间
- 后端返回内容
5. CORS 跨域错误
如果控制台出现:
Access to XMLHttpRequest has been blocked by CORS policy
解决:
- 开发环境用前端代理
- 或后端配置 CORS
注意代理只在开发环境生效,生产环境要用 nginx 或后端 CORS。
6. 请求没有走代理
常见原因:
baseURL: 'http://localhost:8080'
如果你写了完整后端地址,请求就不会走 Vite 代理。
开发环境想走代理,一般写:
baseURL: '/api'
然后由代理转发。
7. 修改代理后不生效
原因:
- 没重启项目
- vite.config.js 写错位置
- 请求路径没有以
/api开头
解决:
npm run dev
重新启动。
十三、生产环境如何处理接口地址?
开发环境可以用 Vite 代理,但生产环境打包后代理不生效。
生产环境常见方案:
方案一:前端直接请求完整 API 域名
.env.production:
VITE_API_BASE_URL=https://api.xxx.com
打包后请求:
https://api.xxx.com/user/list
需要后端配置 CORS。
方案二:Nginx 反向代理
前端部署在:
https://www.xxx.com
接口请求:
https://www.xxx.com/api/user/list
Nginx 配置:
server {
listen 80;
server_name www.xxx.com;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://backend:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
这样生产环境也不会跨域。
十四、联调时前后端怎么高效沟通?
推荐每个问题都按照下面格式反馈:
接口:GET /user/list
环境:http://test-api.xxx.com
问题:返回 500
请求参数:pageNum=1&pageSize=10
请求头:Authorization 已传
返回结果:xxx
复现时间:2025-xx-xx 10:30
截图:Network 截图
不要只说:
接口报错了
这样后端很难排查。
十五、一个完整的 Vue 联调示例
1. .env.development
VITE_API_BASE_URL=/api
2. vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
server: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
}
}
}
})
3. src/utils/request.js
import axios from 'axios'
const request = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL,
timeout: 10000
})
request.interceptors.request.use(config => {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
})
request.interceptors.response.use(
response => {
const res = response.data
if (res.code !== 200) {
return Promise.reject(res)
}
return res.data
},
error => Promise.reject(error)
)
export default request
4. src/api/user.js
import request from '@/utils/request'
export function getUserList(params) {
return request({
url: '/user/list',
method: 'get',
params
})
}
5. 页面调用
<script setup>
import { ref, onMounted } from 'vue'
import { getUserList } from '@/api/user'
const userList = ref([])
onMounted(async () => {
const data = await getUserList({
pageNum: 1,
pageSize: 10
})
userList.value = data.list
})
</script>
请求链路是:
页面调用 getUserList
↓
axios 请求 /api/user/list
↓
Vite dev server 代理
↓
http://localhost:8080/user/list
↓
后端返回数据
↓
响应拦截器处理
↓
页面渲染
十六、总结
Vue 前端和后端联调接口,核心就是这几件事:
- 先确认接口文档:地址、方法、参数、响应结构。
- 配置环境变量:开发、测试、生产环境分开。
- 配置代理解决跨域:Vite 用
server.proxy,Vue CLI 用devServer.proxy。 - 统一封装 axios:处理 baseURL、token、错误码、超时。
- 按模块管理 API:页面只调用业务方法,不直接写请求细节。
- 用 Network 排查问题:看 URL、method、headers、payload、response。
- 生产环境用 Nginx 或 CORS:开发代理打包后不会生效。
- 和后端按请求信息沟通:提供接口、参数、响应、截图,方便定位。
如果是实际项目,推荐形成固定结构:
src/api // 接口方法
src/utils/request.js // axios 封装
.env.* // 环境变量
vite.config.js // 开发代理
这样后续无论是登录、列表、详情、增删改查,联调都会比较清晰、稳定。
更多推荐


所有评论(0)