# axios-miniprogram [![npm version](https://badge.fury.io/js/axios-miniprogram.svg)](https://badge.fury.io/js/axios-miniprogram) [![License: MIT](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://opensource.org/licenses/MIT) ## 安装 ```bash $ yarn add axios-miniprogram ``` 或者 ```bash $ npm i axios-miniprogram ``` ## 简介 为小程序平台量身定制的轻量级请求库,请求配置以微信小程序作为标准,其他平台兼容实现。 - 支持 微信小程序、支付宝小程序、百度小程序、字节跳动小程序、QQ 小程序、uniapp。 - 支持 `Typescript`,健全的类型系统,智能的 `IDE` 提示。 - 支持 `Promise`。 - 支持 拦截器。 - 支持 取消请求。 - 支持 自定义合法状态码。 - 支持 自定义参数序列化。 - 支持 自定义转换数据。 - 支持 自定义错误处理。 - 支持 自定义平台适配器 ## 使用 ### 如何引入 ```typescript // esm import axios from 'axios-miniprogram'; // cjs const axios = require('axios-miniprogram'); // 使用 axios('/user'); ``` ### `axios(config)` 可以通过将相关配置传递给`axios`来发送请求。 ```typescript // 发送 GET 请求 axios({ url: '/user', method: 'get', params: { id: 1, }, }) .then((response) => { // 请求成功后做些什么 }) .catch((error) => { // 请求失败后做些什么 }); // 发送 POST 请求 axios({ url: '/user', method: 'post', data: { id: 1, }, }) .then((response) => { // 请求成功后做些什么 }) .catch((error) => { // 请求失败后做些什么 }); ``` ### `axios(url, config?)` 也可以通过直接把`url`传给`axios`来发送请求。 ```typescript // 默认发送 GET 请求 axios('/user') .then((response) => { // 请求成功后做些什么 }) .catch((error) => { // 请求失败后做些什么 }); // 发送 POST 请求 axios('/user', { method: 'post', }) .then((response) => { // 请求成功后做些什么 }) .catch((error) => { // 请求失败后做些什么 }); ``` 还可以使用请求方法的别名来简化请求。 - ##### axios.request(config) - ##### axios.options(url, config?) - ##### axios.get(url, params?, config?) - ##### axios.head(url, params?, config?) - ##### axios.post(url, data?, config?) - ##### axios.put(url, data?, config?) - ##### axios.delete(url, params?, config?) - ##### axios.trace(url, config?) - ##### axios.connect(url, config?) 常用例子,其他同理: ```typescript // 发送 GET 请求 axios.get('/user'); // 携带参数 axios.get('/user', { test: 1, }); // 携带额外配置 axios.get( '/user', { id: 1, }, { headers: { 'Content-Type': 'application/json; charset=utf-8', }, }, ); // 发送 POST 请求 axios.post('/user'); // 携带数据 axios.post('/user', { id: 1, }); // 携带额外配置 axios.post( '/user', { id: 1, }, { headers: { 'Content-Type': 'application/json; charset=utf-8', }, }, ); ``` ## 动态 URL 您可以使用动态 URL 提高 RESTful API 的书写体验。 ```typescript axios.get('/user/:id', { id: 1, }); // url => '/user/1?id=1' ``` ## 配置`config` 非全平台兼容的属性只会在平台支持的情况下生效。 | 参数 | 类型 | 默认值 | 说明 | 全平台兼容 | | :---------------- | :-----------------------: | :------------------------------------------------------------------------------------ | :----------------- | :--------- | | adapter | Function | [查看](https://github.com/early-autumn/axios-miniprogram/blob/master/src/defaults.ts) | 自定义适配器 | 是 | | baseURL | String | | 基础地址 | 是 | | url | String | | 请求地址 | 是 | | method | String | get | 请求方法 | | | params | Object | | 请求参数 | 是 | | data | String/Object/ArrayBuffer | | 请求数据 | 是 | | headers | Object | [查看](https://github.com/early-autumn/axios-miniprogram/blob/master/src/defaults.ts) | 请求头 | 是 | | validateStatus | Function | [查看](https://github.com/early-autumn/axios-miniprogram/blob/master/src/defaults.ts) | 自定义合法状态码 | 是 | | paramsSerializer | Function | | 自定义参数序列化 | 是 | | transformRequest | Function/Array<.Function> | | 自定义转换请求数据 | 是 | | transformResponse | Function/Array<.Function> | | 自定义转换响应数据 | 是 | | errorHandler | Function | | 自定义错误处理 | 是 | | cancelToken | Object | | 取消令牌 | 是 | | timeout | Number | 10000 | 超时时间 | | | dataType | String | json | 响应数据格式 | 是 | | responseType | String | text | 响应数据类型 | 是 | | enableHttp2 | Boolean | false | 开启 http2 | | | enableQuic | Boolean | false | 开启 quic | | | enableCache | Boolean | false | 开启 cache | | | sslVerify | Boolean | true | 验证 ssl 证书 | | #### `config.method`的合法值 可以使用大写,也可以使用小写。 | 值 | 说明 | 全平台兼容 | | :------ | :--- | :--------- | | OPTIONS | | | | GET | | 是 | | HEAD | | | | POST | | 是 | | PUT | | 是 | | DELETE | | 是 | | TRACE | | | | CONNECT | | | #### `config.dataType`的合法值 | 值 | 说明 | 全平台兼容 | | :--- | :--------------------------------------------------------- | :--------- | | json | 返回的数据为 JSON,返回后会对返回的数据进行一次 JSON.parse | 是 | | 其他 | 不对返回的内容进行 JSON.parse | 是 | #### `config.responseType`的合法值 | 值 | 说明 | 全平台兼容 | | :---------- | :----------------------- | :--------- | | text | 响应的数据为文本 | 是 | | arraybuffer | 响应的数据为 ArrayBuffer | 是 | #### 自定义合法状态码`config.validateStatus` 可以让请求按照您的要求成功或者失败。 ```typescript axios('/user', { validateStatus: function validateStatus(status) { // 这样,状态码在 200 到 400 之间都是请求成功 return status >= 200 && status < 400; }, }); ``` #### 自定义参数序列化`config.paramsSerializer` 可以使用自己的规则去序列化参数。 ```typescript axios('/user', { paramsSerializer: function paramsSerializer(params) { return qs.stringify(params, { arrayFormat: 'brackets', }); }, }); ``` #### 自定义转换数据 可以在请求发出之前转换请求数据,在请求成功之后转换响应数据。 ```typescript axios('/user', { transformRequest: [ function transformRequest(data, headers) { // 转换请求数据 return data; }, ], transformResponse: [ function transformResponse(data) { // 转换响应数据 return data; }, ], }); ``` #### 自定义错误处理`config.errorHandler` 可以添加到默认配置中,统一处理错误。 ```typescript axios.defaults.errorHandler = function errorHandler(error) { // 做一些想做的事情 return Promise.reject(error); }; const instance = axios.create({ errorHandler: function errorHandler(error) { // 做一些想做的事情 return Promise.reject(error); }, }); ``` 也可以发送请求时通过自定义配置传入。 ```typescript axios('/user', { errorHandler: function errorHandler(error) { // 做一些想做的事情 return Promise.reject(error); }, }); ``` #### 自定义平台适配器`config.adapter` 您可以手动适配当前所处的平台。 ```typescript axios.defaults.adapter = function adapter(adapterConfig) { const { // 请求地址 url, // 请求方法 method, // 请求数据 data, // 请求头 同 headers headers, // 请求头 同 headers headers, // 响应数据格式 dataType, // 响应数据类型 responseType, // 超时时间 timeout, // 开启 http2 enableHttp2, // 开启 quic enableQuic, // 开启 cache enableCache, // 验证 ssl 证书 sslVerify, // 成功的回调函数 success, // 失败的回调函数 fail, } = adapterConfig; // 在 adapterConfig 中选择您需要的参数发送请求 return wx.request({ url, method, data, headers, success, fail, }); }; // 如果 adapterConfig 的数据结构适用于当前平台,则可以。 axios.defaults.adapter = wx.request; ``` #### 默认配置`defaults` ##### 全局默认配置`axios.defaults` ```typescript axios.defaults.baseURL = 'https://www.api.com'; axios.defaults.headers.common['Accept'] = 'application/json, test/plain, */*'; axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'; ``` ##### 自定义实例默认配置 可以创建时传入。 ```typescript const instance = axios.create({ baseURL: 'https://www.api.com', headers: { common: { Accept: 'application/json, test/plain, */*', }, post: { 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', }, }, }); ``` 也可以创建后修改。 ```typescript instance.defaults.baseURL = 'https://www.api.com'; instance.defaults.headers.common['Accept'] = 'application/json, test/plain, */*'; instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'; ``` ##### 配置优先顺序 发送请求时,会使用默认配置`defaults`和自定义配置`config`合并出请求配置`requestConfig`,然后用合并出的请求配置`requestConfig`去发送请求,多数情况下,后者优先级要高于前者,具体合并策略可以参考 [mergeConfig.ts](https://github.com/early-autumn/axios-miniprogram/blob/master/src/core/mergeConfig.ts) 的实现。 ## 响应体`response` 非全平台兼容的属性只会在平台支持的情况下生效。 | 属性 | 类型 | 说明 | 全平台兼容 | | :--------- | :------------------------ | :------------------------------------------- | :--------- | | status | Number | 状态码 | 是 | | statusText | String | 状态文本 | 是 | | data | String/Object/ArrayBuffer | 开发者服务器返回的数据 | 是 | | headers | Object | 响应头 | 是 | | config | Object | Axios 请求配置 | 是 | | cookies | Array<.String> | 开发者服务器返回的 cookies,格式为字符串数组 | | | profile | Object | 网络请求过程中一些关键时间点的耗时信息 | | ## API ### `axios.interceptors` 可以先拦截请求或响应,然后再由 then 或 catch 处理。 ```typescript // 添加请求拦截器 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); }, ); ``` 如果以后需要删除拦截器,则可以。 ```typescript const myInterceptor = axios.interceptors.request.use(function () { // 在发送请求之前做些什么 }); axios.interceptors.request.eject(myInterceptor); ``` 还可以将拦截器添加到`axios`的`自定义实例`中。 ```typescript const myInterceptor = instance.interceptors.request.use(function () { // 在发送请求之前做些什么 }); instance.interceptors.request.eject(myInterceptor); ``` ### `axios.CancelToken` 可以使用`CancelToken`取消已经发出的请求。 ```typescript let cancel; axios('/api', { cancelToken: new axios.CancelToken(function (c) { cancel = c; }), }); cancel('取消请求'); ``` 还可以使用`CancelToken.source`工厂方法创建`CancelToken`。 ```typescript const source = axios.CancelToken.source(); axios('/api', { cancelToken: source.token, }); source.cancel('取消请求'); ``` ### `axios.isCancel` 可以判断当前错误是否来自取消请求 ```typescript axios('/user').catch((error) => { if (axios.isCancel(error)) { // 请求被取消了 } }); ``` ### `axios.getUri(config)` 根据配置中的`url`和`params`生成一个`URI`。 ```typescript const uri = axios.getUri({ url: '/user', params: { id: 1, }, }); // '/user?id=1' ``` ### `axios.create(defaults)` 创建一个`自定义实例`,传入的自定义默认配置`defaults`会和`axios`的默认配置`axios.defaults`合并成`自定义实例`的默认配置。 `自定义实例`拥有和`axios`相同的调用方式和请求方法的别名。 ```typescript axios.defaults.baseURL = 'https://www.api.com'; const instance = axios.create({ params: { id: 1, }, }); instance('/user'); // 'https://www.api.com/user?id=1' ``` ### `axios.Axios` `axios.Axios`是一个类,其实`axios`就是`axios.Axios`类的实例改造而来的,`axios.create(defaults)`创建的也是`axios.Axios`的实例。 直接实例化`axios.Axios`可以得到一个`原始实例`,不能当函数调用,传入的自定义配置就是`原始实例`的默认配置,而不会像`axios.create(defaults)`一样去合并`axios`中的默认配置。 ```typescript const instance = new axios.Axios({ beseURL: 'https://www.api.com', params: { id: 1, }, }); instance.get('/user'); // 'https://www.api.com/user?id=1' ``` ## 执行流程 ```typescript axios('/user').then().catch(); // 请求成功 // axios => axios.interceptors.request => config.transformRequest => config.paramsSerializer => config.adapter => config.validateStatus => config.transformResponse => axios.interceptors.response => then // 请求失败 // axios => axios.interceptors.request => config.transformRequest => config.paramsSerializer => config.adapter => config.validateStatus => config.transformResponse => config.errorHandler => axios.interceptors.response => catch ```