Axios是一个基于Promise的HTTP客户端,用于浏览器和Node.js。它可以在浏览器中发送异步请求,也可以在Node.js中发送HTTP请求。Axios可以处理HTTP请求和响应,支持拦截器、取消请求、自动转换JSON数据等功能。在Vue3中,Axios是一个常用的HTTP请求库。
npm install axios
基本结构
import axios from 'axios';
// 发送GET请求
axios.get('/api/user')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// 发送POST请求
axios.post('/api/user', {
firstName: 'John',
lastName: 'Doe'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
GET
import axios from 'axios';
axios.get('/api/user')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
POST
import axios from 'axios';
axios.post('/api/user', {
firstName: 'John',
lastName: 'Doe'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
拦截器
import axios from 'axios';
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
axios.get('/api/user')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
封装示例
// import axios from 'axios'
import qs from 'qs'
import { message } from 'ant-design-vue'
import router from '@/router/index'
import { loadingVisible } from '@/utils/common/visible-data'
import { storage } from '../../utils/storage/storage'
import { removePending, addPending } from './pending'
import { removeUserStorage } from '@/utils/user/user-info'
import { AxiosRequestConfig, AxiosResponse } from 'axios'
// 全局配置
const apiUrl = import.meta.env.VITE_API_DOMAIN
axios.defaults.withCredentials = false
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'
// 允许跨域
axios.defaults.headers.post['Access-Control-Allow-Origin'] = '*'
function myAxios(axiosConfig: AxiosRequestConfig, customOptions: any, loadings: any): Promise<AxiosResponse<any>> {
const { timeout = 8000 } = customOptions
const service = axios.create({
baseURL: apiUrl, // 设置统一的请求前缀
timeout // 设置统一的超时时长
})
// 是否开启/取消重复请求
const cancel = {
cancel_request: false,
...customOptions
}
// 是否开启loading, 默认为 false
const loading = {
loading: loadings.loading
}
// 请求拦截器
service.interceptors.request.use(
(config: AxiosRequestConfig) => {
const { method, data, headers } = config
removePending(config)
cancel.cancel_request && addPending(config)
if (['post', 'put', 'delete'].includes(method as string)) {
config.data = qs.parse(data) //序列化
}
// 若是有做鉴权token , 就给头部带上token
if (storage.get('token')) {
if (headers) {
headers.Authorization = storage.get('token') as string
}
}
// 请求之前发送loading
if (loading.loading) {
loadingVisible.value = true
}
return config
},
error => {
message.error(error.data.error.message)
return Promise.reject(error.data.error.message)
}
)
// 响应拦截器
service.interceptors.response.use(
(res: AxiosResponse<any>) => {
// 在请求结束后,移除本次请求
removePending(res)
// 请求之后关闭loading
if (loading.loading) {
setTimeout(function () {
loadingVisible.value = false
}, 500)
}
// 对响应数据进行处理,例如检查统一的字段(如 statusCode)
if (res.status === 200 || res.data.statusCode === 200) {
return Promise.resolve(res)
}
return Promise.reject(res)
},
error => {
loadingVisible.value = false
const statusTextMap: Record<number, string> = {
400: '发出的请求有错误,服务器没有进行新建或修改数据的操作',
401: '登录失效,请重新登录',
403: '用户得到授权,但是访问是被禁止的',
404: '网络请求不存在',
406: '请求的格式不可得',
410: '请求的资源被永久删除,且不会再得到的',
422: '当创建一个对象时,发生一个验证错误',
500: '服务器发生错误,请检查服务器',
502: '网关错误',
503: '服务不可用,服务器暂时过载或维护',
504: '网关超时'
}
if (error.response && error.response.status) {
const statusText = statusTextMap[error.response.status] ?? '其他错误'
message.error(`${statusText}(${error.response.status})`)
if (error.response.status === 401) {
removeUserStorage()
router.replace({
path: '/Login'
})
}
return Promise.reject(error)
}
return Promise.reject(new Error('网络请求失败,请稍后重试'))
}
)
return service(axiosConfig)
}
export default myAxios
main.ts
全局使用
import axios from './utils/http/axios'
// 全局ctx(this) 上挂载 $axios
app.config.globalProperties.$api = axios
调用
import request from '@/utils/http/axios'
import { IntArticle } from "@/api/data/interData";
export class article {
static async GetCountAsync() {
return await request({
url: "/api/SnArticle/GetCountAsync",
method: 'get',
})
}
static async AddAsync(resultData: IntArticle) {
return await
request({
url: "/api/SnArticle/AddAsync",
method: "post",
data: resultData,
})
}
static async UpdateAsync(resultData: IntArticle) {
return await
request({
url: "/api/SnArticle/UpdateAsync",
method: "put",
data: resultData,
})
}
static async DeleteAsync(id: number) {
return await
request({
url: "/api/SnArticle/DeleteAsync?id=" + id,
method: "delete",
})
}
}
并发请求
处理并发请求的助手函数
axios.all(iterable)
axios.spread(callback)
import { article } from '@/api/index';
import { blogsList } from "./components/data";
import axios from '@/utils/http/axios'
class methods {
static async GetFySortTitle() {
await article.GetFySortTitleAsync(blogsList.page, blogsList.pagesize, true).then((res: any) => {
blogsList.dataResult = res.data;
});
}
static async ConutSort() {
await article.ConutSort(7).then((result: any) => {
blogsList.count = result.data;
});
}
}
async function QueryAll() {
// axios.all([await methods.ConutSort(), await methods.GetFySortTitle()]).then(axios.spread((Fy, co: any) => {
// blogsList.count = co.data;
// blogsList.dataResult = Fy.data;
// }))
axios.all([await methods.ConutSort(), await methods.GetFySortTitle()])
}
export {
methods,
QueryAll
}