2023-05-05 10:59:37 +08:00
|
|
|
|
import { isFunction, isPlainObject } from '../helpers/isTypes';
|
|
|
|
|
import { transformURL } from '../helpers/transformURL';
|
2023-04-21 18:09:32 +08:00
|
|
|
|
import {
|
2023-05-05 10:59:37 +08:00
|
|
|
|
AxiosRequestConfig,
|
|
|
|
|
AxiosResponse,
|
|
|
|
|
AxiosResponseError,
|
|
|
|
|
} from '../core/Axios';
|
2023-03-23 20:09:00 +08:00
|
|
|
|
import {
|
2023-05-05 10:59:37 +08:00
|
|
|
|
AxiosAdapterRequestConfig,
|
|
|
|
|
AxiosAdapterResponse,
|
|
|
|
|
AxiosAdapterResponseError,
|
|
|
|
|
AxiosAdapterPlatformTask,
|
|
|
|
|
AxiosAdapterRequestMethod,
|
|
|
|
|
} from '../adpater/createAdapter';
|
|
|
|
|
import { isCancelToken } from './cancel';
|
|
|
|
|
import { AxiosErrorResponse, createError } from './createError';
|
|
|
|
|
import { generateType } from './generateType';
|
2023-03-23 20:09:00 +08:00
|
|
|
|
|
2023-04-18 23:08:49 +08:00
|
|
|
|
/**
|
|
|
|
|
* 开始请求
|
|
|
|
|
*
|
|
|
|
|
* 创建适配器配置并调用适配器,监听取消请求,注册监听回调,处理响应体和错误体,抛出异常。
|
|
|
|
|
*
|
|
|
|
|
* @param config 请求配置
|
|
|
|
|
*/
|
2023-04-09 15:20:10 +08:00
|
|
|
|
export function request(config: AxiosRequestConfig) {
|
2023-05-05 10:59:37 +08:00
|
|
|
|
return new Promise<AxiosResponse>((resolve, reject) => {
|
|
|
|
|
const adapterConfig: AxiosAdapterRequestConfig = {
|
|
|
|
|
...(config as AxiosAdapterRequestConfig),
|
|
|
|
|
type: generateType(config),
|
|
|
|
|
url: transformURL(config),
|
|
|
|
|
method: config.method!.toUpperCase() as AxiosAdapterRequestMethod,
|
|
|
|
|
success,
|
|
|
|
|
fail,
|
|
|
|
|
};
|
2023-03-23 20:09:00 +08:00
|
|
|
|
|
2023-05-05 10:59:37 +08:00
|
|
|
|
let adapterTask: AxiosAdapterPlatformTask;
|
|
|
|
|
try {
|
|
|
|
|
adapterTask = config.adapter!(adapterConfig);
|
|
|
|
|
} catch (err) {
|
|
|
|
|
fail({
|
|
|
|
|
status: 400,
|
|
|
|
|
statusText: 'Bad Adapter',
|
|
|
|
|
});
|
2023-04-20 10:57:10 +08:00
|
|
|
|
|
2023-05-05 10:59:37 +08:00
|
|
|
|
console.error(err);
|
|
|
|
|
}
|
2023-03-23 20:09:00 +08:00
|
|
|
|
|
2023-05-05 10:59:37 +08:00
|
|
|
|
function success(baseResponse: AxiosAdapterResponse): void {
|
|
|
|
|
const response = baseResponse as AxiosResponse;
|
|
|
|
|
response.status = response.status ?? 200;
|
|
|
|
|
response.statusText = response.statusText ?? 'OK';
|
|
|
|
|
response.headers = response.headers ?? {};
|
|
|
|
|
response.config = config;
|
|
|
|
|
response.request = adapterTask;
|
2023-04-09 15:20:10 +08:00
|
|
|
|
|
2023-05-05 10:59:37 +08:00
|
|
|
|
const { validateStatus } = config;
|
|
|
|
|
if (!isFunction(validateStatus) || validateStatus(response.status)) {
|
|
|
|
|
resolve(response);
|
|
|
|
|
} else {
|
|
|
|
|
catchError('validate status error', response);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-03-23 20:09:00 +08:00
|
|
|
|
|
2023-05-05 10:59:37 +08:00
|
|
|
|
function fail(baseResponseError: AxiosAdapterResponseError): void {
|
|
|
|
|
const responseError = baseResponseError as AxiosResponseError;
|
|
|
|
|
responseError.isFail = true;
|
|
|
|
|
responseError.status = responseError.status ?? 400;
|
|
|
|
|
responseError.statusText = responseError.statusText ?? 'Fail';
|
|
|
|
|
responseError.headers = responseError.headers ?? {};
|
|
|
|
|
responseError.config = config;
|
|
|
|
|
responseError.request = adapterTask;
|
2023-04-18 11:14:57 +08:00
|
|
|
|
|
2023-05-05 10:59:37 +08:00
|
|
|
|
catchError('request fail', responseError);
|
|
|
|
|
}
|
2023-03-23 20:09:00 +08:00
|
|
|
|
|
2023-05-05 10:59:37 +08:00
|
|
|
|
function catchError(
|
|
|
|
|
message: string,
|
|
|
|
|
errorResponse: AxiosErrorResponse,
|
|
|
|
|
): void {
|
|
|
|
|
reject(createError(message, config, errorResponse, adapterTask));
|
|
|
|
|
}
|
2023-03-23 20:09:00 +08:00
|
|
|
|
|
2023-05-05 10:59:37 +08:00
|
|
|
|
if (isPlainObject(adapterTask)) {
|
|
|
|
|
tryToggleProgressUpdate(adapterConfig, adapterTask.onProgressUpdate);
|
|
|
|
|
}
|
2023-03-23 20:09:00 +08:00
|
|
|
|
|
2023-05-05 10:59:37 +08:00
|
|
|
|
const { cancelToken } = config;
|
|
|
|
|
if (isCancelToken(cancelToken)) {
|
|
|
|
|
cancelToken.onCancel((reason) => {
|
|
|
|
|
if (isPlainObject(adapterTask)) {
|
|
|
|
|
tryToggleProgressUpdate(adapterConfig, adapterTask.offProgressUpdate);
|
2023-03-23 20:09:00 +08:00
|
|
|
|
|
2023-05-05 10:59:37 +08:00
|
|
|
|
adapterTask?.abort?.();
|
|
|
|
|
}
|
2023-03-23 20:09:00 +08:00
|
|
|
|
|
2023-05-05 10:59:37 +08:00
|
|
|
|
reject(reason);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
2023-03-23 20:09:00 +08:00
|
|
|
|
}
|
2023-04-18 23:08:49 +08:00
|
|
|
|
|
|
|
|
|
function tryToggleProgressUpdate(
|
2023-05-05 10:59:37 +08:00
|
|
|
|
config: AxiosAdapterRequestConfig,
|
|
|
|
|
progress?: (cb: (event: AnyObject) => void) => void,
|
2023-04-18 23:08:49 +08:00
|
|
|
|
) {
|
2023-05-05 10:59:37 +08:00
|
|
|
|
const { type, onUploadProgress, onDownloadProgress } = config;
|
|
|
|
|
if (isFunction(progress)) {
|
|
|
|
|
switch (type) {
|
|
|
|
|
case 'upload':
|
|
|
|
|
if (isFunction(onUploadProgress)) {
|
|
|
|
|
progress(onUploadProgress);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'download':
|
|
|
|
|
if (isFunction(onDownloadProgress)) {
|
|
|
|
|
progress(onDownloadProgress);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-18 23:08:49 +08:00
|
|
|
|
}
|