还记得刚学Vue时被HTTP请求支配的恐惧吗?每个组件里都在重复写着一模一样的代码:
// 每个组件都在重复这些代码,烦不烦?
axios.post('https://api.yoursite.com/v1/users', data, {
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json'
}
})
一个月后,后端告诉你:“哥们,域名从 https://api.yoursite.com 换成 https://api.newdomain.com 了...”
然后你哭着在整个项目里查找替换几十个接口地址——别问我是怎么知道的,说多了都是泪。
为什么你需要Axios默认配置?
Axios默认配置就像是给你的请求找了个贴心管家,把那些重复性的琐事统统搞定。想象一下,你不再需要:
- 在每个请求里写完整的URL
- 手动添加认证token
- 重复设置content-type
- 为每个请求单独处理错误
Axios的默认配置能帮你做什么?
简单说就是“一次设置,到处使用”。你定义一次规则,Axios会在每个请求中自动应用这些规则。这不仅仅是代码整洁的问题,更是维护性和开发效率的质的飞跃。
手把手配置:从入门到精通
1. 基础配置:让你的代码瞬间清爽
先来看一个最基本的配置:
// axios默认配置
axios.defaults.baseURL = 'https://api.yoursite.com/v1'
axios.defaults.timeout = 10000 // 10秒超时
axios.defaults.headers.common['Content-Type'] = 'application/json'
// 然后你的请求就变成了这样:
// 之前:axios.post('https://api.yoursite.com/v1/users', data, config)
// 现在:
axios.post('/users', data) // 清爽!
看到区别了吗?baseURL 设置了基础路径,后续所有相对路径都会自动拼接。这就好比给所有请求加了个通用前缀,再也不用担心域名变更了。
2. 实战中的完整配置示例
光说不练假把式,来看一个真实项目中的配置:
// src/utils/request.js
import axios from 'axios'
// 创建axios实例
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // 从环境变量读取
timeout: 15000, // 15秒超时
headers: {
'Content-Type': 'application/json;charset=utf-8'
}
})
// 请求拦截器 - 在发送请求前做点什么
service.interceptors.request.use(
config => {
// 每次请求自动添加token
const token = localStorage.getItem('access_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) {
return res
} else {
// 处理业务错误
alert(res.message || '请求失败')
return Promise.reject(new Error(res.message || 'Error'))
}
},
error => {
// 处理HTTP错误
if (error.response?.status === 401) {
// token过期,跳转到登录页
localStorage.removeItem('access_token')
window.location.href = '/login'
} else if (error.response?.status === 500) {
alert('服务器内部错误,请稍后重试')
}
return Promise.reject(error)
}
)
export default service
然后在你的Vue组件中:
// 在组件中使用
import request from '@/utils/request'
export default {
methods: {
async getUserInfo() {
try {
// 看,多简洁!
const userData = await request.get('/user/info')
const listData = await request.post('/list', { page: 1 })
this.user = userData
this.list = listData
} catch (error) {
console.log('请求失败', error)
}
}
}
}
3. 环境区分:开发、测试、生产无缝切换
真实项目中,不同环境需要不同的配置:
// .env.development
VUE_APP_BASE_API = 'https://dev-api.yoursite.com'
// .env.production
VUE_APP_BASE_API = 'https://api.yoursite.com'
// 在axios配置中使用
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
// ...其他配置
})
这样,打包到不同环境时会自动使用对应的接口地址,再也不用手动修改了。
拦截器:Axios的灵魂所在
如果说默认配置是基础装备,那拦截器就是神级装备。它让你能够在请求和响应的生命周期中插入自定义逻辑。
请求拦截器的妙用:
service.interceptors.request.use(
config => {
// 显示loading
showLoading()
// 记录请求开始时间(用于性能监控)
config.metadata = { startTime: new Date() }
// 如果是文件上传,修改content-type
if (config.data instanceof FormData) {
config.headers['Content-Type'] = 'multipart/form-data'
}
return config
}
)
响应拦截器的威力:
service.interceptors.response.use(
response => {
// 隐藏loading
hideLoading()
// 计算请求耗时
const endTime = new Date()
const duration = endTime - response.config.metadata.startTime
console.log(`请求 ${response.config.url} 耗时 ${duration}ms`)
return response.data
},
error => {
hideLoading()
// 统一错误处理
if (!error.response) {
// 网络错误
alert('网络连接失败,请检查网络设置')
}
return Promise.reject(error)
}
)
高级技巧:让你的Axios配置更智能
1. 重试机制:网络不稳定时的救星
service.interceptors.response.use(
response => response,
async error => {
const { config, response } = error
// 只在网络错误或5xx错误时重试
if (!response || response.status >= 500) {
if (!config.retryCount) {
config.retryCount = 0
}
if (config.retryCount < 3) {
config.retryCount++
// 等待2的n次方秒后重试(2, 4, 8秒)
const waitTime = Math.pow(2, config.retryCount) * 1000
await new Promise(resolve => setTimeout(resolve, waitTime))
return service(config)
}
}
return Promise.reject(error)
}
)
2. 请求取消:避免重复请求
const pendingRequests = new Map()
// 生成请求的唯一标识
function getRequestKey(config) {
return [config.method, config.url].join('&')
}
// 请求拦截器中
service.interceptors.request.use(config => {
const key = getRequestKey(config)
if (pendingRequests.has(key)) {
// 取消重复请求
pendingRequests.get(key)('取消重复请求')
}
config.cancelToken = new axios.CancelToken(cancel => {
pendingRequests.set(key, cancel)
})
return config
})
// 响应拦截器中
service.interceptors.response.use(
response => {
const key = getRequestKey(response.config)
pendingRequests.delete(key)
return response
},
error => {
if (axios.isCancel(error)) {
console.log('请求被取消:', error.message)
}
return Promise.reject(error)
}
)
3. 文件上传进度监控
// 上传文件时显示进度
async uploadFile(file, onProgress) {
const formData = new FormData()
formData.append('file', file)
const response = await request.post('/upload', formData, {
onUploadProgress: progressEvent => {
if (onProgress) {
const percent = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
onProgress(percent)
}
}
})
return response
}
常见坑点及解决方案
坑点1:默认配置不生效
// 错误写法:创建实例后修改defaults对实例无效
const instance = axios.create()
instance.defaults.timeout = 1000 // 这样写无效!
// 正确写法:在create时传入配置,或使用instance的配置
const instance = axios.create({
timeout: 1000 // 正确
})
// 或者
instance.defaults.timeout = 1000 // 这样也正确
坑点2:拦截器中的异步问题
// 错误:在拦截器中直接使用async/await但不返回
service.interceptors.request.use(async config => {
await someAsyncOperation() // 这样会出问题!
return config
})
// 正确:确保正确处理异步
service.interceptors.request.use(async config => {
await someAsyncOperation()
return config // 正确返回
})
完整示例:开箱即用的Axios配置
最后,送大家一个生产环境可用的完整配置:
// src/utils/request.js
import axios from 'axios'
import { Message } from 'element-ui' // 如果你用了Element UI
class Request {
constructor() {
this.instance = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 15000,
withCredentials: true // 跨域时携带cookie
})
this.setupInterceptors()
}
setupInterceptors() {
// 请求拦截
this.instance.interceptors.request.use(
config => {
// 添加时间戳防止缓存
if (config.method === 'get') {
config.params = {
...config.params,
_t: Date.now()
}
}
const token = localStorage.getItem('token')
if (token) {
config.headers['Authorization'] = `Bearer ${token}`
}
return config
},
error => Promise.reject(error)
)
// 响应拦截
this.instance.interceptors.response.use(
response => {
const { data } = response
// 根据你的后端数据结构调整
if (data.code === 0 || data.success) {
return data
} else {
Message.error(data.message || '请求失败')
return Promise.reject(new Error(data.message || 'Error'))
}
},
error => {
const { status } = error.response || {}
switch (status) {
case 400:
Message.error('请求错误')
break
case 401:
Message.error('未授权,请重新登录')
localStorage.removeItem('token')
setTimeout(() => {
window.location.href = '/login'
}, 1500)
break
case 403:
Message.error('拒绝访问')
break
case 404:
Message.error('请求地址出错')
break
case 500:
Message.error('服务器内部错误')
break
default:
Message.error('网络连接失败')
}
return Promise.reject(error)
}
)
}
get(url, params = {}) {
return this.instance.get(url, { params })
}
post(url, data = {}) {
return this.instance.post(url, data)
}
put(url, data = {}) {
return this.instance.put(url, data)
}
delete(url, params = {}) {
return this.instance.delete(url, { params })
}
}
export default new Request()
结语
Axios的默认配置和拦截器就像是给你的项目请了一个24小时在线的贴心助理。它帮你处理各种重复劳动,让你能专注于核心业务逻辑。
从今天开始,告别重复代码,拥抱高效的Axios配置吧!你的键盘会感谢你,你的队友也会感谢你——毕竟,谁不喜欢简洁清晰的代码呢?
记住:好的配置不是炫技,而是为了让代码更可维护、更健壮、更优雅。现在就去优化你的Axios配置吧,保证让你直呼“真香”!
Axios默认配置提升开发效率

被折叠的 条评论
为什么被折叠?



