mp-mini-axios
v1.6.3
Published
MiniAxios 是一个轻量级 HTTP 客户端库,专为【微信小程序】设计,提供类似 Axios 的 API 接口。它支持请求/响应拦截器、取消请求、自动重试、文件上传/下载等功能。构建后大小11KB,能有效节省小程序包大小。
Maintainers
Readme
MiniAxios 使用文档
MiniAxios 是一个轻量级 HTTP 客户端库,专为【微信小程序】设计,提供类似 Axios 的 API 接口。它支持请求/响应拦截器、取消请求、自动重试、文件上传/下载等功能。构建后大小11KB,能有效节省小程序包大小。
关于模块名称与类名
最开始,打算把模块叫做mini-axios,发布...重名。改名为nano-axios,还得意洋洋写了句,nano < mirco < mini,发布...又重!又改名为mp-axios,又说和mp_axios太像,最终改为mp-mini-axios。由于开发的时候使用了MiniAxios作为类名,这里就不改了。
安装与引入
1. 使用模块
// 1. 安装模块
npm i mp-mini-axios;
// 2. 构建npm
微信开发者工具 > 工具 > 构建 npm
// 3. 项目引入
import axios, { MiniAxios, CancelToken, AbortController } from 'mp-mini-axios';
2. 复制源码到项目
将模块中的源码复制到小程序项目中:
src/index.js- 导出文件src/MiniAxios.js- 核心库src/CancelToken.js- 取消令牌实现src/AbortController.js- 中止控制器实现
import axios, { MiniAxios, CancelToken, AbortController } from './libs/miniAxios/index.js';
import axios, { MiniAxios } from './libs/miniAxios/MiniAxios.js';
import { CancelToken } from './libs/miniAxios/CancelToken.js';
import { AbortController } from './libs/miniAxios/AbortController.js';创建实例
1. 使用默认实例
// 使用默认配置
axios.get('/api/data')
.then(response => console.log(response.data))
.catch(error => console.error(error));2. 使用工厂函数创建实例
// 使用 create 方法创建实例
const api = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000,
headers: {
'X-Custom-Header': 'custom-value'
}
});
// 使用自定义实例
api.post('/users', { name: 'John' })
.then(response => console.log(response.data))
.catch(error => console.error(error));3. 使用类创建实例
// 创建自定义实例
const api = new MiniAxios({
baseURL: 'https://api.example.com',
timeout: 10000,
headers: {
'X-Custom-Header': 'custom-value'
}
});
// 使用自定义实例
api.post('/users', { name: 'John' })
.then(response => console.log(response.data))
.catch(error => console.error(error));配置项
MiniAxios 支持以下配置选项:
| 配置项 | 类型 | 默认值 | 说明 |
|--------|------|---------|------|
| baseURL | string | '' | 基础 URL |
| timeout | number | 60000 | 请求超时时间(ms) |
| headers/header | object | {} | 请求头 |
| retry | boolean/number | false | 是否重试及重试次数 |
| retryDelay | number | 1000 | 重试延迟时间(ms) |
| method | string | 'get' | 请求方法 |
| params/query | object | {} | URL 查询参数 |
| data/body | object | {} | 请求体数据 |
| filePath | string | '' | 文件路径(上传/下载) |
| name/fileName | string | 'file' | 文件字段名(上传) |
| cancelToken | CancelToken | null | 取消令牌 |
| signal | AbortSignal | null | 中止信号 |
| onRetry | function | null | 重试回调 |
| onProgressUpdate | function | null | 进度更新回调 |
| onHeadersReceived | function | null | 头部接收回调 |
| enableCache | boolean | false | 是否启用缓存 |
| enableHttp2 | boolean | false | 是否启用 HTTP/2 |
| enableQuic | boolean | false | 是否启用 QUIC |
请求方法
1. 基本请求方法
// GET 请求
axios.get('/api/data', {
params: { id: 123 }
}).then(response => console.log(response.data));
// POST 请求
axios.post('/api/users', {
name: 'John',
age: 30
}).then(response => console.log('创建成功'));
// PUT 请求
axios.put('/api/users/123', {
name: 'John Updated'
}).then(response => console.log('更新成功'));
// DELETE 请求
axios.delete('/api/users/123')
.then(response => console.log('删除成功'));
// HEAD 请求
axios.head('/api/data')
.then(response => console.log(response.headers));
// OPTIONS 请求
axios.options('/api/data')
.then(response => console.log(response.headers));2. 通用请求方法
axios.request({
url: '/api/data',
method: 'post',
data: { key: 'value' },
headers: {
'Content-Type': 'application/json'
}
}).then(response => console.log(response.data));文件上传与下载
1. 文件上传
// uploadFile(config)
// uploadFile(url, config)
// uploadFile(url, formData, config)
axios.uploadFile('/upload', {
description: '用户头像'
otherFormData: 'xxx',
}, {
filePath: '/path/to/avatar.jpg',
name: 'avatar', // 可选,默认 'file'
onProgressUpdate: progress => {
console.log(`上传进度: ${progress.progress}%`);
}
}).then(response => {
console.log('上传成功', response.data);
}).catch(error => {
console.error('上传失败', error);
});2. 文件下载
// downloadFile(config)
// downloadFile(url, config)
axios.downloadFile('/file.pdf', {
filePath: '/path/to/save.pdf',
onProgressUpdate: progress => {
console.log(`下载进度: ${progress.progress}%`);
}
}).then(response => {
console.log('下载成功', response.data.tempFilePath);
}).catch(error => {
console.error('下载失败', error);
});拦截器
1. 请求拦截器
// 添加请求拦截器
axios.interceptors.request.use(config => {
// 添加认证令牌
config.headers.Authorization = 'Bearer token';
// 记录请求日志
console.log('发送请求:', config.url);
return config;
}, error => {
// 处理请求错误
return Promise.reject(error);
});2. 响应拦截器
// 添加响应拦截器
axios.interceptors.response.use(response => {
// 处理响应数据
console.log('收到响应:', response.status);
// 只返回数据部分
return response.data;
}, error => {
// 处理响应错误
if (error.response && error.response.status === 401) {
// 处理未授权错误
console.log('未授权,跳转到登录页');
}
return Promise.reject(error);
});3. 移除拦截器
// 添加拦截器
const interceptorId = axios.interceptors.request.use(/* ... */);
// 移除拦截器
axios.interceptors.request.eject(interceptorId);取消请求
1. 使用 CancelToken
// 创建取消令牌
const source = CancelToken.source();
// 发起请求
axios.get('/api/data', {
cancelToken: source.token
}).catch(error => {
if (MiniAxios.isCancel(error)) {
console.log('请求已取消:', error.message);
}
});
// 取消请求
source.cancel('用户取消了请求');2. 使用 AbortController
// 创建中止控制器
const controller = new AbortController();
// 发起请求
axios.get('/api/data', {
signal: controller.signal
}).catch(error => {
if (error.code === 'ECONNABORTED') {
console.log('请求已中止:', error.message);
}
});
// 中止请求
controller.abort('用户中止了请求');错误处理
1. 错误对象结构
错误对象包含以下属性:
{
message: '错误消息',
code: '错误代码',
config: '请求配置',
request: '请求对象',
response: '响应对象(如果有)',
status: 'HTTP状态码',
retryCount: '重试次数(如果有)'
}2. 常见错误代码
| 错误代码 | 说明 |
|----------|------|
| ETIMEDOUT | 请求超时 |
| ECONNABORTED | 请求被中止 |
| ERR_BAD_REQUEST | 客户端错误(4xx) |
| ERR_BAD_RESPONSE | 服务器错误(5xx) |
| WX_API_ERROR | 微信API错误 |
3. 错误处理示例
axios.get('/api/data')
.then(response => console.log(response.data))
.catch(error => {
if (error.code === 'ETIMEDOUT') {
console.log('请求超时');
} else if (error.code === 'ECONNABORTED') {
console.log('请求被中止');
} else if (error.response) {
console.log(`服务器错误: ${error.response.status}`);
} else {
console.log('未知错误', error);
}
});重试机制
1. 基本重试配置
axios.get('/api/data', {
retry: 3, // 重试3次
retryDelay: 2000, // 每次重试间隔2秒
onRetry: (retryInfo) => {
console.log(`重试 #${retryInfo.retryCount}, 错误: ${retryInfo.error.message}`);
}
}).then(response => {
console.log('最终响应:', response.data);
}).catch(error => {
console.log('最终失败:', error.message);
});2. 指数退避策略
MiniAxios 默认使用指数退避策略:
- 第一次重试延迟:
retryDelay - 第二次重试延迟:
retryDelay * 2 - 第三次重试延迟:
retryDelay * 4 - 以此类推
完整配置示例
// 创建自定义实例
const api = new MiniAxios({
baseURL: 'https://api.example.com',
timeout: 15000,
headers: {
'X-Client': 'MiniApp'
},
retry: 2,
retryDelay: 1000
});
// 添加拦截器
api.interceptors.request.use(config => {
config.headers.Authorization = 'Bearer token';
return config;
});
api.interceptors.response.use(response => {
return response.data;
}, error => {
return Promise.reject(error);
});
// 发起请求
api.post('/users', {
name: 'John',
email: '[email protected]'
}, {
onProgressUpdate: progress => {
console.log(`请求进度: ${progress.progress}%`);
}
}).then(data => {
console.log('用户创建成功', data);
}).catch(error => {
console.error('创建用户失败', error);
});注意事项
小程序限制:
- 文件上传需使用
wx.uploadFile - 文件下载需使用
wx.downloadFile - 部分 API 在小程序中有特殊限制
- 文件上传需使用
取消请求:
- 小程序中取消请求使用
requestTask.abort() - 取消后请求会立即失败
- 小程序中取消请求使用
错误处理:
- 使用自定义错误类
- 错误对象中包含微信原生错误信息
重试机制:
- 默认只对非取消错误重试
- 可自定义重试条件和重试策略
性能优化:
- 避免在拦截器中执行耗时操作
- 合理设置超时时间
- 按需使用重试机制
最佳实践
- 封装 API 模块:
// api.js
import axios from 'mp-mini-axios';
const api = axios.create({
baseURL: 'https://api.example.com'
});
export default {
getUsers: () => api.get('/users'),
createUser: (userData) => api.post('/users', userData),
uploadAvatar: (filePath, data) => api.uploadFile('/upload/avatar', data, { filePath })
};- 统一错误处理:
// 全局错误处理
api.interceptors.response.use(null, error => {
if (error.response && error.response.status === 401) {
// 跳转到登录页
wx.redirectTo({ url: '/pages/login' });
}
return Promise.reject(error);
});- 请求取消封装:
// 封装可取消请求
function makeCancelableRequest(request) {
const source = CancelToken.source();
const requestPromise = request(source.token);
return {
promise: requestPromise,
cancel: (message) => source.cancel(message || '请求已取消')
};
}
// 使用
const { promise, cancel } = makeCancelableRequest(
token => api.get('/data', { cancelToken: token })
);
// 取消请求
cancel();- 上传/下载进度显示:
// 上传文件显示进度
api.uploadFile('/upload', {}, {
filePath: '/path/to/file',
onProgressUpdate: progress => {
wx.showToast({
title: `上传中 ${progress.progress}%`,
icon: 'none'
});
}
});总结
MiniAxios 为微信小程序提供了强大的 HTTP 客户端功能,主要特点包括:
- 类 Axios API:熟悉的 API 设计,降低学习成本
- 请求/响应拦截器:灵活处理请求和响应
- 取消请求:支持 CancelToken 和 AbortController 两种方式
- 自动重试:内置指数退避重试策略
- 文件支持:简化文件上传/下载操作
- 错误处理:统一错误处理机制
- 配置灵活:支持全局配置和请求级配置
通过合理使用 MiniAxios,可以大大简化小程序中的网络请求处理,提高开发效率和代码质量。
