1. 完整的实例配置
// http.js
import axios from 'axios'
const instance = axios.create({
// 基础URL,会自动加在请求URL前面
baseURL: process.env.VUE_APP_API_URL,
// 请求超时时间(毫秒)
timeout: 5000,
// 自定义请求头
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
'platform': 'web'
},
// 是否携带cookie信息
withCredentials: true,
// 请求体编码方式
responseType: 'json',
// 用于限制请求内容的大小
maxContentLength: 2000,
// 用于限制上传内容的大小
maxBodyLength: 2000,
// 自定义验证状态码的范围
validateStatus: function (status) {
return status >= 200 && status < 300
}
})
2. 详细的拦截器配置
// interceptors.js
/**
* 请求拦截器配置
* @param {Object} config - 请求配置对象
* @returns {Object} 处理后的请求配置
*/
instance.interceptors.request.use(
config => {
// 1. 添加 loading 效果
startLoading()
// 2. 添加token
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
// 3. GET请求添加时间戳防止缓存
if (config.method === 'get') {
config.params = {
...config.params,
_t: Date.now()
}
}
// 4. POST请求数据处理
if (config.method === 'post') {
// 4.1 数据转换
if (config.headers['Content-Type'] === 'application/x-www-form-urlencoded') {
config.data = qs.stringify(config.data)
}
// 4.2 数据加密(如果需要)
if (config.needEncrypt) {
config.data = encrypt(config.data)
}
}
// 5. 添加自定义请求头
config.headers['X-Custom-Header'] = 'custom-value'
return config
},
error => {
stopLoading()
return Promise.reject(error)
}
)
/**
* 响应拦截器配置
* @param {Object} response - 响应对象
* @returns {Object} 处理后的响应数据
*/
instance.interceptors.response.use(
response => {
// 1. 关闭 loading 效果
stopLoading()
// 2. 获取响应数据
const { code, data, message } = response.data
// 3. 处理不同状态码
switch (code) {
case 200:
return data
case 401:
handleUnauthorized()
break
case 403:
handleForbidden()
break
default:
handleError(message)
}
return Promise.reject(new Error(message))
},
error => {
stopLoading()
// 1. 处理请求超时
if (error.code === 'ECONNABORTED' && error.message.includes('timeout')) {
handleTimeout()
return Promise.reject(new Error('请求超时'))
}
// 2. 处理网络错误
if (!error.response) {
handleNetworkError()
return Promise.reject(new Error('网络错误'))
}
// 3. 处理HTTP错误
const { status } = error.response
handleHttpError(status)
return Promise.reject(error)
}
)
3. 完整的错误处理模块
// errorHandler.js
/**
* 统一的错误处理模块
*/
export const ErrorHandler = {
// 处理未授权错误
handleUnauthorized() {
// 1. 清除本地token
localStorage.removeItem('token')
// 2. 显示错误消息
Message.error('登录已过期,请重新登录')
// 3. 跳转登录页
router.push({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
})
},
// 处理权限不足
handleForbidden() {
Message.error('您没有权限访问该资源')
router.push('/403')
},
// 处理请求超时
handleTimeout() {
Message.error('请求超时,请稍后重试')
},
// 处理网络错误
handleNetworkError() {
Message.error('网络连接失败,请检查网络设置')
},
// 处理HTTP错误
handleHttpError(status) {
const errorMap = {
400: '请求参数错误',
401: '未授权,请登录',
403: '拒绝访问',
404: '请求地址出错',
408: '请求超时',
500: '服务器内部错误',
501: '服务未实现',
502: '网关错误',
503: '服务不可用',
504: '网关超时',
505: 'HTTP版本不受支持'
}
Message.error(errorMap[status] || `未知错误:${status}`)
}
}
4. 请求方法封装
// request.js
/**
* 请求方法封装
* @param {string} url - 请求地址
* @param {Object} params - 请求参数
* @param {Object} options - 配置选项
*/
export const request = {
/**
* GET请求
* @param {string} url - 请求地址
* @param {Object} params - URL参数
* @param {Object} options - 配置选项
*/
async get(url, params = {}, options = {}) {
try {
const config = {
...options,
params: {
...params,
_t: Date.now() // 防止缓存
}
}
return await instance.get(url, config)
} catch (error) {
handleRequestError(error)
throw error
}
},
/**
* POST请求
* @param {string} url - 请求地址
* @param {Object} data - 请求体数据
* @param {Object} options - 配置选项
*/
async post(url, data = {}, options = {}) {
try {
const config = {
...options,
headers: {
'Content-Type': 'application/json',
...options.headers
}
}
return await instance.post(url, data, config)
} catch (error) {
handleRequestError(error)
throw error
}
},
/**
* 文件上传
* @param {string} url - 上传地址
* @param {File} file - 文件对象
* @param {Object} options - 配置选项
*/
async upload(url, file, options = {}) {
const formData = new FormData()
formData.append('file', file)
try {
const config = {
...options,
headers: {
'Content-Type': 'multipart/form-data',
...options.headers
},
onUploadProgress: progressEvent => {
const complete = (progressEvent.loaded / progressEvent.total * 100 | 0)
options.onProgress?.(complete)
}
}
return await instance.post(url, formData, config)
} catch (error) {
handleRequestError(error)
throw error
}
},
/**
* 文件下载
* @param {string} url - 下载地址
* @param {string} filename - 文件名
* @param {Object} options - 配置选项
*/
async download(url, filename, options = {}) {
try {
const config = {
...options,
responseType: 'blob',
onDownloadProgress: progressEvent => {
const complete = (progressEvent.loaded / progressEvent.total * 100 | 0)
options.onProgress?.(complete)
}
}
const response = await instance.get(url, config)
const blob = new Blob([response.data])
const downloadUrl = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = downloadUrl
link.download = filename
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(downloadUrl)
return response
} catch (error) {
handleRequestError(error)
throw error
}
}
}
5. API模块封装示例
// api/user.js
/**
* 用户相关API
*/
export const userApi = {
/**
* 获取用户列表
* @param {Object} params - 查询参数
* @param {number} params.page - 页码
* @param {number} params.size - 每页数量
* @returns {Promise} 用户列表数据
*/
getUsers(params) {
return request.get('/users', params)
},
/**
* 创建用户
* @param {Object} data - 用户数据
* @returns {Promise} 创建结果
*/
createUser(data) {
return request.post('/users', data)
},
/**
* 更新用户信息
* @param {string|number} id - 用户ID
* @param {Object} data - 更新数据
* @returns {Promise} 更新结果
*/
updateUser(id, data) {
return request.put(`/users/${id}`, data)
},
/**
* 删除用户
* @param {string|number} id - 用户ID
* @returns {Promise} 删除结果
*/
deleteUser(id) {
return request.delete(`/users/${id}`)
}
}
6. 使用示例
// 组件中使用
import { userApi } from '@/api/user'
export default {
data() {
return {
users: [],
loading: false,
query: {
page: 1,
size: 10
}
}
},
methods: {
// 获取用户列表
async fetchUsers() {
try {
this.loading = true
const data = await userApi.getUsers(this.query)
this.users = data.list
this.total = data.total
} catch (error) {
console.error('获取用户列表失败:', error)
} finally {
this.loading = false
}
},
// 创建用户
async createUser(userData) {
try {
await userApi.createUser(userData)
this.$message.success('创建成功')
this.fetchUsers()
} catch (error) {
this.$message.error('创建失败')
}
}
}
}
这个完整的 Axios 配置和使用方案包含了:
- 详细的实例配置
- 完整的拦截器处理
- 统一的错误处理
- 规范的请求方法封装
- 标准的 API 模块组织
- 实际的使用示例
每个部分都有详细的注释说明,便于理解和使用。这种方案可以作为一个完整的项目请求层解决方案。