parent
158d26fa64
commit
a04f833d91
|
@ -123,7 +123,6 @@ function sidebar() {
|
||||||
{ text: '创建实例', link: '/advanced/instance' },
|
{ text: '创建实例', link: '/advanced/instance' },
|
||||||
{ text: '扩展实例', link: '/advanced/extend' },
|
{ text: '扩展实例', link: '/advanced/extend' },
|
||||||
{ text: '平台适配器', link: '/advanced/adapter' },
|
{ text: '平台适配器', link: '/advanced/adapter' },
|
||||||
{ text: '派生领域(即将废弃)', link: '/advanced/fork' },
|
|
||||||
],
|
],
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
},
|
},
|
||||||
|
|
|
@ -20,7 +20,7 @@ import axios from 'axios-miniprogram';
|
||||||
axios.defaults.baseURL = 'https://api.com';
|
axios.defaults.baseURL = 'https://api.com';
|
||||||
|
|
||||||
// 相对地址会进行组合
|
// 相对地址会进行组合
|
||||||
// baseURL 最终结果为 https://api.com/uesr
|
// baseURL 最终结果为 https://api.com/user
|
||||||
const instance = axios.extend({
|
const instance = axios.extend({
|
||||||
baseURL: 'user',
|
baseURL: 'user',
|
||||||
headers: {
|
headers: {
|
||||||
|
|
|
@ -1,228 +0,0 @@
|
||||||
---
|
|
||||||
title: 派生领域
|
|
||||||
---
|
|
||||||
|
|
||||||
# {{ $frontmatter.title }}
|
|
||||||
|
|
||||||
::: tip {{ $frontmatter.title }}
|
|
||||||
派生新的领域简化 `URL`。
|
|
||||||
:::
|
|
||||||
|
|
||||||
::: warning 注意
|
|
||||||
该接口即将废弃,请使用功能更强的[扩展实例](./extend)。
|
|
||||||
:::
|
|
||||||
|
|
||||||
## 派生领域
|
|
||||||
|
|
||||||
可以基于 `axios` 派生领域,配置项 `baseURL` 传相对地址时会和 `axios.defaults.baseURL` 一起组合成完整的服务端地址。
|
|
||||||
|
|
||||||
全局默认配置 `axios.defaults` 和派生领域时传入的配置 `config` 将会按优先级[合并](/basics/defaults#配置合并策略)成领域默认配置 `domain.defaults`。
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import axios from 'axios-miniprogram';
|
|
||||||
|
|
||||||
axios.defaults.baseURL = 'https://api.com';
|
|
||||||
|
|
||||||
// 相对地址会进行组合
|
|
||||||
// baseURL 最终结果为 https://api.com/uesr
|
|
||||||
const domain = axios.fork({
|
|
||||||
baseURL: 'user',
|
|
||||||
headers: {
|
|
||||||
common: {
|
|
||||||
['Content-Type']: 'application/json',
|
|
||||||
},
|
|
||||||
post: {
|
|
||||||
['Content-Type']: 'application/x-www-form-urlencoded',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
timeout: 1000,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 绝对地址会直接使用
|
|
||||||
// baseURL 最终结果为 https://api2.com/user
|
|
||||||
const domain = axios.fork({
|
|
||||||
baseURL: 'https://api2.com/user',
|
|
||||||
headers: {
|
|
||||||
common: {
|
|
||||||
['Content-Type']: 'application/json',
|
|
||||||
},
|
|
||||||
post: {
|
|
||||||
['Content-Type']: 'application/x-www-form-urlencoded',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
timeout: 1000,
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## 默认配置
|
|
||||||
|
|
||||||
可以设置配置项默认值。
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import axios from 'axios-miniprogram';
|
|
||||||
|
|
||||||
axios.defaults.baseURL = 'https://api.com';
|
|
||||||
|
|
||||||
const domain = axios.fork({
|
|
||||||
baseURL: 'user',
|
|
||||||
});
|
|
||||||
|
|
||||||
domain.defaults.headers.common['Content-Type'] = 'application/json';
|
|
||||||
domain.defaults.timeout = 1000;
|
|
||||||
```
|
|
||||||
|
|
||||||
## 拦截器
|
|
||||||
|
|
||||||
可以使用父级的拦截器,但不支持为领域单独添加拦截器。
|
|
||||||
|
|
||||||
基于 axios 派生领域。
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import axios from 'axios-miniprogram';
|
|
||||||
|
|
||||||
// 请求拦截器
|
|
||||||
axios.interceptors.request.use(
|
|
||||||
function (config) {
|
|
||||||
// 在发送请求之前做些什么
|
|
||||||
return config;
|
|
||||||
},
|
|
||||||
function (error) {
|
|
||||||
// 对请求错误做些什么
|
|
||||||
return Promise.reject(error);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// 响应拦截器
|
|
||||||
axios.interceptors.response.use(
|
|
||||||
function (response) {
|
|
||||||
// 在 then 之前做些什么
|
|
||||||
return response;
|
|
||||||
},
|
|
||||||
function (error) {
|
|
||||||
// 在 catch 之前做些什么
|
|
||||||
return Promise.reject(error);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const domain = axios.fork({
|
|
||||||
baseURL: 'test',
|
|
||||||
});
|
|
||||||
|
|
||||||
// 发送请求时会使用 axios 的请求拦截器和响应拦截器
|
|
||||||
domain.get('/');
|
|
||||||
```
|
|
||||||
|
|
||||||
基于实例派生领域。
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import axios from 'axios-miniprogram';
|
|
||||||
|
|
||||||
const instance = axios.create({
|
|
||||||
baseURL: 'https://api.com',
|
|
||||||
});
|
|
||||||
|
|
||||||
// 请求拦截器
|
|
||||||
instance.interceptors.request.use(
|
|
||||||
function (config) {
|
|
||||||
// 在发送请求之前做些什么
|
|
||||||
return config;
|
|
||||||
},
|
|
||||||
function (error) {
|
|
||||||
// 对请求错误做些什么
|
|
||||||
return Promise.reject(error);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// 响应拦截器
|
|
||||||
instance.interceptors.response.use(
|
|
||||||
function (response) {
|
|
||||||
// 在 then 之前做些什么
|
|
||||||
return response;
|
|
||||||
},
|
|
||||||
function (error) {
|
|
||||||
// 在 catch 之前做些什么
|
|
||||||
return Promise.reject(error);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const domain = instance.fork({
|
|
||||||
baseURL: 'test',
|
|
||||||
});
|
|
||||||
|
|
||||||
// 发送请求时会使用 instance 的请求拦截器和响应拦截器
|
|
||||||
domain.get('/');
|
|
||||||
```
|
|
||||||
|
|
||||||
## 使用方式
|
|
||||||
|
|
||||||
可以使用请求方法发送请求。
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import axios from 'axios-miniprogram';
|
|
||||||
|
|
||||||
axios.defaults.baseURL = 'https://api.com';
|
|
||||||
|
|
||||||
const domain = axios.fork({
|
|
||||||
baseURL: 'user',
|
|
||||||
});
|
|
||||||
|
|
||||||
// 请求的服务端地址 https://api.com/uesr/1
|
|
||||||
domain
|
|
||||||
.get('/:id', {
|
|
||||||
id: 1,
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
// 成功之后做些什么
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
// 失败之后做些什么
|
|
||||||
});
|
|
||||||
|
|
||||||
// 请求的服务端地址 https://api.com/uesr
|
|
||||||
domain
|
|
||||||
.post('/', {
|
|
||||||
id: 1,
|
|
||||||
name: 'user',
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
// 成功之后做些什么
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
// 失败之后做些什么
|
|
||||||
});
|
|
||||||
|
|
||||||
// 请求的服务端地址 https://api.com/uesr/1
|
|
||||||
domain
|
|
||||||
.put('/:id', {
|
|
||||||
name: 'user',
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
// 成功之后做些什么
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
// 失败之后做些什么
|
|
||||||
});
|
|
||||||
|
|
||||||
// 请求的服务端地址 https://api.com/uesr/1
|
|
||||||
domain
|
|
||||||
.delete('/:id', {
|
|
||||||
id: 1,
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
// 成功之后做些什么
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
// 失败之后做些什么
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
- [domain.request(url, config?) | domain.request(config)](/basics/request)
|
|
||||||
- [domain.options(url, config?)](/method/OPTIONS)
|
|
||||||
- [domain.get(url, params?, config?)](/method/GET)
|
|
||||||
- [domain.head(url, params?, config?)](/method/HEAD)
|
|
||||||
- [domain.post(url, data?, config?)](/method/POST)
|
|
||||||
- [domain.put(url, data?, config?)](/method/PUT)
|
|
||||||
- [domain.patch(url, data?, config?)](/method/PATCH)
|
|
||||||
- [domain.delete(url, params?, config?)](/method/DELETE)
|
|
||||||
- [domain.trace(url, config?)](/method/TRACE)
|
|
||||||
- [domain.connect(url, config?)](/method/CONNECT)
|
|
|
@ -99,7 +99,7 @@ const child = instance.extend({
|
||||||
baseURL: 'user',
|
baseURL: 'user',
|
||||||
});
|
});
|
||||||
|
|
||||||
// 请求的服务端地址 https://api2.com/uesr
|
// 请求的服务端地址 https://api2.com/user
|
||||||
child('/');
|
child('/');
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,10 @@ title: 中间件
|
||||||
## 前言
|
## 前言
|
||||||
|
|
||||||
如果您了解或者使用过[koa](https://github.com/koajs/koa),相信您一定十分了解什么是洋葱模型,中间件该怎么写。
|
如果您了解或者使用过[koa](https://github.com/koajs/koa),相信您一定十分了解什么是洋葱模型,中间件该怎么写。
|
||||||
|
|
||||||
中间件是一个异步函数,接收 `context` 和 `next` 两个参数。
|
中间件是一个异步函数,接收 `context` 和 `next` 两个参数。
|
||||||
|
|
||||||
`context` 是一个对象,提供了 `req` 对象和 `res` 对象作为其做成部分。
|
`context` 是一个对象,提供了 `req` 对象和 `res` 对象作为其组成部分。
|
||||||
|
|
||||||
- `context.req`:请求配置。
|
- `context.req`:请求配置。
|
||||||
- `context.res`:请求完成后服务端返回的响应体,它的初始值是 `null`,请求完成之后才能对其进行操作。
|
- `context.res`:请求完成后服务端返回的响应体,它的初始值是 `null`,请求完成之后才能对其进行操作。
|
||||||
|
@ -117,6 +118,6 @@ instance.use(async (ctx, next) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// 复用父级中间件
|
// 复用父级中间件
|
||||||
// axios request -> instance request -> https://api.com/test/uesr -> instance response -> axios response
|
// axios request -> instance request -> https://api.com/test/user -> instance response -> axios response
|
||||||
instance('/user');
|
instance('/user');
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { isFunction, isPlainObject } from '../helpers/types';
|
import { isFunction, isPlainObject } from '../helpers/types';
|
||||||
import { assert } from '../helpers/error';
|
import { assert } from '../helpers/error';
|
||||||
import { origIgnore } from '../helpers/ignore';
|
import { orgIgnore } from '../helpers/ignore';
|
||||||
import {
|
import {
|
||||||
AxiosProgressEvent,
|
AxiosProgressEvent,
|
||||||
AxiosRequestFormData,
|
AxiosRequestFormData,
|
||||||
|
@ -281,6 +281,7 @@ export function createAdapter(platform: AxiosAdapterPlatform) {
|
||||||
errMsg: responseError.errMsg ?? responseError.errorMessage,
|
errMsg: responseError.errMsg ?? responseError.errorMessage,
|
||||||
errno: responseError.errno ?? responseError.error,
|
errno: responseError.errno ?? responseError.error,
|
||||||
};
|
};
|
||||||
|
|
||||||
transformResponse(responseError);
|
transformResponse(responseError);
|
||||||
config.fail(responseError);
|
config.fail(responseError);
|
||||||
},
|
},
|
||||||
|
@ -293,7 +294,7 @@ export function createAdapter(platform: AxiosAdapterPlatform) {
|
||||||
response.status = response.status ?? response.statusCode;
|
response.status = response.status ?? response.statusCode;
|
||||||
response.headers = response.headers ?? response.header;
|
response.headers = response.headers ?? response.header;
|
||||||
|
|
||||||
origIgnore(response, [
|
orgIgnore(response, [
|
||||||
'statusCode',
|
'statusCode',
|
||||||
'errMsg',
|
'errMsg',
|
||||||
'errno',
|
'errno',
|
||||||
|
@ -324,8 +325,7 @@ export function createAdapter(platform: AxiosAdapterPlatform) {
|
||||||
options.fileType = fileType;
|
options.fileType = fileType;
|
||||||
options.formData = formData;
|
options.formData = formData;
|
||||||
|
|
||||||
origIgnore(options, ['params', 'data']);
|
orgIgnore(options, ['params', 'data']);
|
||||||
|
|
||||||
return upload(options);
|
return upload(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,18 +340,16 @@ export function createAdapter(platform: AxiosAdapterPlatform) {
|
||||||
response.data = {
|
response.data = {
|
||||||
filePath: response.filePath,
|
filePath: response.filePath,
|
||||||
tempFilePath:
|
tempFilePath:
|
||||||
response.tempFilePath ||
|
response.tempFilePath ??
|
||||||
// response.apFilePath 为支付宝小程序基础库小于 2.7.23 的特有属性。
|
// response.apFilePath 为支付宝小程序基础库小于 2.7.23 的特有属性。
|
||||||
response.apFilePath,
|
response.apFilePath,
|
||||||
};
|
};
|
||||||
|
|
||||||
origIgnore(response, ['tempFilePath', 'apFilePath', 'filePath']);
|
orgIgnore(response, ['tempFilePath', 'apFilePath', 'filePath']);
|
||||||
|
|
||||||
success(response);
|
success(response);
|
||||||
};
|
};
|
||||||
|
|
||||||
origIgnore(options, ['params']);
|
orgIgnore(options, ['params']);
|
||||||
|
|
||||||
return download(options);
|
return download(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,9 @@ import { AxiosAdapterPlatform, createAdapter } from './createAdapter';
|
||||||
*/
|
*/
|
||||||
export function getDefaultAdapter() {
|
export function getDefaultAdapter() {
|
||||||
const platform = revisePlatformApiNames(getPlatform());
|
const platform = revisePlatformApiNames(getPlatform());
|
||||||
if (!isPlatform(platform)) {
|
if (isPlatform(platform)) {
|
||||||
return;
|
return createAdapter(platform);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPlatform() {
|
function getPlatform() {
|
||||||
|
@ -35,13 +36,13 @@ export function getDefaultAdapter() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function revisePlatformApiNames(platform?: AnyObject) {
|
function revisePlatformApiNames(platform?: AnyObject) {
|
||||||
return (
|
if (platform) {
|
||||||
platform && {
|
return {
|
||||||
request: platform.request ?? platform.httpRequest,
|
request: platform.request ?? platform.httpRequest,
|
||||||
upload: platform.upload ?? platform.uploadFile,
|
upload: platform.upload ?? platform.uploadFile,
|
||||||
download: platform.download ?? platform.downloadFile,
|
download: platform.download ?? platform.downloadFile,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPlatform(value: any): value is AxiosAdapterPlatform {
|
function isPlatform(value: any): value is AxiosAdapterPlatform {
|
||||||
|
@ -52,6 +53,3 @@ export function getDefaultAdapter() {
|
||||||
isFunction(value.download)
|
isFunction(value.download)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return createAdapter(platform);
|
|
||||||
}
|
|
||||||
|
|
|
@ -44,14 +44,6 @@ export interface AxiosInstance extends AxiosRequest, Axios {
|
||||||
* @param config 默认配置
|
* @param config 默认配置
|
||||||
*/
|
*/
|
||||||
extend(config: AxiosRequestConfig): AxiosInstance;
|
extend(config: AxiosRequestConfig): AxiosInstance;
|
||||||
/**
|
|
||||||
* 派生领域
|
|
||||||
*
|
|
||||||
* @param config 默认配置
|
|
||||||
*
|
|
||||||
* @deprecated 请使用 extend 替换 fork
|
|
||||||
*/
|
|
||||||
fork(config: AxiosRequestConfig): AxiosInstance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createInstance(
|
export function createInstance(
|
||||||
|
@ -72,7 +64,6 @@ export function createInstance(
|
||||||
config.baseURL = combineURL(defaults.baseURL, config.baseURL);
|
config.baseURL = combineURL(defaults.baseURL, config.baseURL);
|
||||||
return createInstance(mergeConfig(defaults, config), context);
|
return createInstance(mergeConfig(defaults, config), context);
|
||||||
};
|
};
|
||||||
instance.fork = instance.extend;
|
|
||||||
|
|
||||||
Object.assign(instance, context);
|
Object.assign(instance, context);
|
||||||
Object.setPrototypeOf(instance, Axios.prototype);
|
Object.setPrototypeOf(instance, Axios.prototype);
|
||||||
|
|
|
@ -9,7 +9,7 @@ export function ignore<T extends AnyObject, K extends keyof T>(
|
||||||
...keys: K[]
|
...keys: K[]
|
||||||
): Omit<T, K> {
|
): Omit<T, K> {
|
||||||
const res = { ...obj };
|
const res = { ...obj };
|
||||||
origIgnore(res, keys);
|
orgIgnore(res, keys);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ export function ignore<T extends AnyObject, K extends keyof T>(
|
||||||
* @param obj 源对象
|
* @param obj 源对象
|
||||||
* @param keys 忽略的键
|
* @param keys 忽略的键
|
||||||
*/
|
*/
|
||||||
export function origIgnore(obj: AnyObject, keys: PropertyKey[]) {
|
export function orgIgnore(obj: AnyObject, keys: PropertyKey[]) {
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
delete obj[key as string | number];
|
delete obj[key as string | number];
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@ describe('src/axios.ts', () => {
|
||||||
});
|
});
|
||||||
expect(instance.interceptors).toBeTypeOf('object');
|
expect(instance.interceptors).toBeTypeOf('object');
|
||||||
expect(instance.getUri).toBeTypeOf('function');
|
expect(instance.getUri).toBeTypeOf('function');
|
||||||
expect(instance.fork).toBeTypeOf('function');
|
|
||||||
expect(instance.request).toBeTypeOf('function');
|
expect(instance.request).toBeTypeOf('function');
|
||||||
|
|
||||||
eachMethods((k) => {
|
eachMethods((k) => {
|
||||||
|
|
|
@ -19,7 +19,6 @@ describe('src/axios.ts', () => {
|
||||||
expect(axios.create).toBeTypeOf('function');
|
expect(axios.create).toBeTypeOf('function');
|
||||||
expect(axios.extend).toBeTypeOf('function');
|
expect(axios.extend).toBeTypeOf('function');
|
||||||
expect(axios.use).toBeTypeOf('function');
|
expect(axios.use).toBeTypeOf('function');
|
||||||
expect(axios.fork).toBeTypeOf('function');
|
|
||||||
expect(axios.request).toBeTypeOf('function');
|
expect(axios.request).toBeTypeOf('function');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ describe('src/core/createInstance.ts', () => {
|
||||||
expect(i.getUri).toBeTypeOf('function');
|
expect(i.getUri).toBeTypeOf('function');
|
||||||
expect(i.create).toBeTypeOf('function');
|
expect(i.create).toBeTypeOf('function');
|
||||||
expect(i.extend).toBeTypeOf('function');
|
expect(i.extend).toBeTypeOf('function');
|
||||||
expect(i.fork).toBeTypeOf('function');
|
|
||||||
expect(i.use).toBeTypeOf('function');
|
expect(i.use).toBeTypeOf('function');
|
||||||
expect(i.request).toBeTypeOf('function');
|
expect(i.request).toBeTypeOf('function');
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { describe, test, expect } from 'vitest';
|
import { describe, test, expect } from 'vitest';
|
||||||
import { ignore, origIgnore } from '@/helpers/ignore';
|
import { ignore, orgIgnore } from '@/helpers/ignore';
|
||||||
|
|
||||||
describe('src/helpers/ignore.ts', () => {
|
describe('src/helpers/ignore.ts', () => {
|
||||||
test('不应该改变传递的对象', () => {
|
test('不应该改变传递的对象', () => {
|
||||||
|
@ -55,20 +55,20 @@ describe('src/helpers/ignore.ts', () => {
|
||||||
v3: [],
|
v3: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
origIgnore(o, ['v1']);
|
orgIgnore(o, ['v1']);
|
||||||
|
|
||||||
expect(o).toEqual({
|
expect(o).toEqual({
|
||||||
v2: {},
|
v2: {},
|
||||||
v3: [],
|
v3: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
origIgnore(o, ['v2']);
|
orgIgnore(o, ['v2']);
|
||||||
|
|
||||||
expect(o).toEqual({
|
expect(o).toEqual({
|
||||||
v3: [],
|
v3: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
origIgnore(o, ['v3']);
|
orgIgnore(o, ['v3']);
|
||||||
|
|
||||||
expect(o).toEqual({});
|
expect(o).toEqual({});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue