前端开发里,和后端接口打交道是绕不开的事儿,而Axios作为当下热门的HTTP请求工具,和Web API的对接更是核心环节,你是不是也遇到过“请求发出去了但没数据”“跨域报错一头雾水”“token加了还是没权限”这些问题?这篇文章就用问答思路,把axios对接WEB API的门道拆明白,从基础到实战,再到踩坑解决,帮你把数据交互这事儿理顺!
很多刚入门的同学会疑惑:axiOS是干啥的?Web API又是什么?简单说,axIOS是个能在浏览器和node.js里发http请求的工具,基于Promise设计,写代码时链式调用或者async/await都很顺手,而Web API是后端开发同学提供的“数据接口”,比如你做电商项目,获取商品列表、下单这些功能,后端会暴露对应的API地址(像/api/goods、/api/order),前端通过请求这些地址来拿数据或者提交数据。
举个生活例子:你去奶茶店点单(前端发请求),菜单就是Web API里的“接口列表”(哪些能点),店员接收你的订单并和后厨沟通(后端处理请求),最后把奶茶给你(返回响应),axios就像是你和店员沟通的“语言工具”,让这个过程更顺畅。
为啥选axios对接Web API?它有几个硬优势:一是自动把响应数据转成json,不用自己手动parse;二是能设置请求拦截器、响应拦截器,统一处理token、loading这些逻辑;三是对请求取消、超时控制这些细节支持得很友好,比起原生fetch或者XMLHttpRequest,写代码效率高太多。
axios对接Web API的核心步骤是啥?
想让axios和Web API“打通”,得按步骤来,每一步都有讲究:
把axios引进项目里
如果是vue、react这类前端框架项目,一般用npm安装:npm install axios,然后在需要的文件里引入:import axios from 'axios';,要是纯静态页面,用CDN更方便:<script src="https://cdn.JSdelivr.net/npm/axios/dist/axios.min.js"></script>,这样全局就有axios对象了。
配置基础信息,减少重复代码
每个Web API都有固定的基础地址,比如后端接口统一是https://api.myblog.com/v1开头,那可以给axios设置baseurl,以后发请求就不用每次写完整地址,还能设置超时时间(比如5秒没响应就报错)、请求头(比如默认加Content-type),代码长这样:
const request = axios.create({ baseURL: 'HTTPS://api.myblog.com/v1', // 后端API的基础地址 timeout: 5000, // 超时时间,单位毫秒 headers: { 'Content-Type': 'APPlication/JSON' } // 默认请求头 });
这样创建的request实例,后续发请求更简洁,还能给不同模块(比如用户模块、文章模块)创建不同实例,管理更灵活。
发起基本请求:get、post怎么用?
Web API最常用的就是GET(查数据)、POST(提交数据)这些请求方式,用axios写起来很直观:
GET请求(拿数据):比如获取文章列表,后端接口是
/articles,还能传页码参数,用axios的话:
// 方式一:params传参
request.get('/articles', {
params: { page: 1, size: 10 } // 会自动拼到url后面变成?page=1&size=10
}).then(res => {
console.log('文章列表', res.data); // res.data是后端返回的实际数据
}).catch(err => {
console.error('请求失败', err);
});
// 方式二:async/Await(更简洁)
Async function getArticles() {
try {
const res = await request.get('/articles', { params: { page: 1 } });
return res.data;
} catch (err) {
// 处理错误
}
}POST请求(提交数据):比如用户注册,后端接口是
/users/register,需要传用户名、密码,代码:
const userInfo = { username: '小明', password: '123456' };
request.post('/users/register', userInfo)
.then(res => {
console.log('注册成功', res.data);
})
.catch(err => {
if (err.response) {
// 后端返回了错误状态码,比如400(参数错)、500(服务器炸了)
console.log('后端返回错误:', err.response.data.msg);
} else {
// 网络问题,比如断网、超时
console.log('网络请求失败');
}
});这里要注意,POST请求的第二个参数是请求体(body),axios会根据请求头自动处理格式,如果是表单提交(Content-Type是application/x-www-FORM-urlencoded),得用qs库把对象转成键值对格式,
import qs from 'qs';
const userInfo = { username: '小明', password: '123456' };
request.post('/users/login', qs.stringify(userInfo), {
headers: { 'Content-Type': 'Application/x-www-form-urlencoded' }
});响应和错误怎么处理更稳?
后端返回的数据里,一般会有状态码(比如200成功,401没权限,500服务器错)和数据体,axios的响应对象res里,res.data才是后端真正返回的业务数据,res.status是HTTP状态码,res.headers是响应头。
错误处理分两种情况:一是请求发出去了但后端返回错误状态码(比如400、404),这时err.response存在;二是请求没发出去(比如网络断了、超时),这时err.response是undefined,所以catch里要分情况处理:
async function FetchData() { try { const res = awAIt request.get('/some-api'); // 成功,处理res.data } catch (err) { if (err.response) { // 后端返回错误 const { status, data } = err.response; if (status === 401) { // 没权限,跳登录页 window.location.href = '/login'; } else if (status === 400) { alert('参数错误:' + data.msg); } } else { // 网络或超时错误 alert('请检查网络连接'); } } }
对接时最容易踩的坑,咋解决?
很多同学跟着步骤做还是会报错,这部分把高频问题拎出来,教你怎么破:
跨域报错:No 'Access-Control-Allow-Origin' header...
这是浏览器的同源策略搞的鬼(协议、域名、端口有一个不一样就算跨域),解决得前后端配合:
后端配置CORS:后端在响应头里加
Access-Control-Allow-Origin: *(开发时可以,生产要限制域名),还要允许对应的请求方法(GET、POST等)和请求头,比如Node.js的Express框架,装cors中间件:npm install cors,然后用:
const cors = reqUIre('cors'); app.use(cors());
module.Exports = { devServer: { proxy: { '/api': { target: 'https://api.myblog.com', // 后端真实地址 changeOrigin: true, // 开启代理 pathRewrite: { '^/api': '' } // 把请求里的/api替换成空 } } } };
这样前端发请求到/api/articles,会被代理到https://api.myblog.com/articles,绕开跨域限制。
多次请求重复,数据覆盖(竞态问题)
比如用户快速点“刷新列表”按钮,多次发GET请求,后发的请求先返回,导致界面显示旧数据,解决用axios的取消请求功能:
let cancelToken = null; async function refreshlist() { // 每次请求前,取消上一次的请求 if (cancelToken) { cancelToken.cancel('请求被取消'); } cancelToken = axios.CancelToken.source(); // 创建新的取消令牌 try { const res = await request.get('/articles', { cancelToken: cancelToken.token }); // 处理数据 } catch (err) { if (axios.isCancel(err)) { console.log('请求被取消', err.message); } else { // 其他错误处理 } } }
token失效或权限不足(401错误)
后端一般用token做身份验证,请求时要把token放到请求头里,可以用**请求拦截器**统一加token:
request.interceptors.request.use(config => { const token = localStorage.getItem('token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }, err => { return promise.reject(err); });
然后用**响应拦截器**处理401错误(比如token过期,跳登录页):
request.interceptors.response.use(res => {
return res;
}, err => {
if (err.response && err.response.status === 401) {
// 清除过期token
localStorage.removeItem('token');
// 跳转到登录页
window.location.href = '/login';
}
return Promise.reject(err);
});数据格式不对,后端收不到或前端解析错
比如前端发POST请求,后端期望form-data格式,但前端用了json格式,就会解析失败,这时候要检查请求头和数据格式:
const formData = new FormData(); formData.append('username', '小明'); formData.append('avatar', file); // 上传文件时用FormData更方便 request.post('/users/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' } });
后端返回非JSON格式:比如返回纯文本,axios默认会尝试转JSON导致报错,这时候在请求配置里加
responseType: 'text':
request.get('/api/text', {
responseType: 'text'
}).then(res => {
console.log(res.data); // 现在是纯文本
});实战:用axios对接RESTful Web API做个博客系统
光说不练假把式,现在模拟一个博客系统的核心功能,看axios怎么和Web API配合:
场景:用户登录 + 获取文章列表 + 发布文章
配置axios实例(统一管理基础地址、token)
import axios from 'axios';
// 创建带配置的axios实例
const api = axios.create({
baseURL: 'https://api.blogdemo.com/v1',
timeout: 6000,
headers: { 'Content-Type': 'application/json' }
});
// 请求拦截器:加token
api.interceptors.request.use(config => {
const token = localStorage.getItem('blog_token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
// 响应拦截器:处理401
api.interceptors.response.use(res => res, err => {
if (err.response?.status === 401) {
localStorage.removeItem('blog_token');
window.location.href = '/login.html';
}
return Promise.reject(err);
});
export default api;用户登录功能(POST请求)
import api from './api'; // 登录函数 export async function login(user) { try { const res = await api.post('/auth/login', user); // 登录成功,存token localStorage.setItem('blog_token', res.data.token); return res.data; // 返回用户信息 } catch (err) { if (err.response) { // 后端返回错误,比如账号密码错 return { code: err.response.status, msg: err.response.data.msg }; } else { return { code: 500, msg: '网络连接失败' }; } } } // 调用登录 const user = { username: 'test', password: '123' }; login(user).then(res => { if (res.code === 200) { alert('登录成功'); } else { alert(res.msg); } });
获取文章列表(GET请求,带参数)
export async function getArticleList(page = 1) {
try {
const res = await api.get('/articles', {
params: { page, size: 10 }
});
return res.data.list; // 假设后端返回{ list: [...], total: 100 }
} catch (err) {
console.error('获取文章列表失败', err);
return [];
}
}
// 调用
getArticleList(1).then(list => {
if (list.length) {
// 渲染到页面
renderArticles(list);
} else {
alert('暂无文章');
}
});发布文章(POST请求,带token)
export async function publishArticle(data) {
try {
const res = await api.post('/articles', data);
return res.data; // 后端返回文章ID等信息
} catch (err) {
if (err.response) {
return { code: err.response.status, msg: err.response.data.msg };
} else {
return { code: 500, msg: '发布失败,请检查网络' };
}
}
}
// 调用:假设data是{ title: '我的第一篇博客', content: '正文...' }
const articleData = { title: '测试', content: '内容' };
publishArticle(articleData).then(res => {
if (res.Code === 200) {
alert('发布成功,文章ID:' + res.data.id);
} else {
alert(res.msg);
}
});这个实战案例里,能看到axios实例的配置、拦截器的作用、不同请求的写法,还有错误处理的细节,实际项目中,还可以把这些函数封装到vuex的action里,或者React的hooks中,让组件更简洁。
进阶:让axios对接更高效的技巧
把基础流程跑通后,还要优化体验和代码质量,这些技巧能帮你更上一层楼:
拦截器玩出花:统一处理loading、错误提示
很多项目里,发请求时要显示loading,请求结束后隐藏,用请求拦截器和响应拦截器统一处理:
// 全局loading(假设用Element-UI的Loading组件) import { Loading } from 'element-ui'; let loadingInstance = Null; // 请求拦截器:显示loading api.interceptors.request.use(config => { loadingInstance = Loading.service({ fullscreen: true }); return config; }, err => { loadingInstance.close(); return Promise.reject(err); }); // 响应拦截器:隐藏loading api.interceptors.response.use(res => { loadingInstance.close(); return res; }, err => { loadingInstance.close(); if (err.response?.status === 401) { // 之前的处理 } return Promise.reject(err); });
这样所有请求都会自动显示loading,不用每个请求都写重复代码。
封装请求工具:减少重复,提高可维护性
把常用的GET、POST、PUT、DELETE封装


网友回答文明上网理性发言 已有0人参与
发表评论: