fix: 修复部分 bug
parent
d1956cd9ef
commit
3dd5b26375
|
@ -1,17 +1,3 @@
|
||||||
/**
|
|
||||||
* feat:新增功能
|
|
||||||
* fix:bug 修复
|
|
||||||
* docs:文档更新
|
|
||||||
* style:不影响程序逻辑的代码修改(修改空白字符,格式缩进,补全缺失的分号等,没有改变代码逻辑)
|
|
||||||
* refactor:重构代码(既没有新增功能,也没有修复 bug)
|
|
||||||
* perf:性能, 体验优化
|
|
||||||
* test:新增测试用例或是更新现有测试
|
|
||||||
* build:主要目的是修改项目构建系统(例如 glup,webpack,rollup 的配置等)的提交
|
|
||||||
* ci:主要目的是修改项目继续集成流程(例如 Travis,Jenkins,GitLab CI,Circle等)的提交
|
|
||||||
* chore:不属于以上类型的其他类型,比如构建流程, 依赖管理
|
|
||||||
* revert:回滚某个更早之前的提交
|
|
||||||
*/
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
extends: ['@commitlint/config-conventional'],
|
extends: ['@commitlint/config-conventional'],
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "axios-miniprogram",
|
"name": "axios-miniprogram",
|
||||||
"version": "1.3.1",
|
"version": "2.0.0_rc_1",
|
||||||
"description": "基于 Promise 的 HTTP 请求库,适用于各大小程序平台。",
|
"description": "基于 Promise 的 HTTP 请求库,适用于各大小程序平台。",
|
||||||
"main": "dist/cjs/axios-miniprogram.js",
|
"main": "dist/cjs/axios-miniprogram.js",
|
||||||
"module": "dist/esm/axios-miniprogram.js",
|
"module": "dist/esm/axios-miniprogram.js",
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rollup --config",
|
"build": "rollup --config",
|
||||||
"test": "jest",
|
"test": "jest --passWithNoTests",
|
||||||
"lint": "eslint",
|
"lint": "eslint",
|
||||||
"format": "prettier --check --write '{src,__tests__}/**/*.{js,ts,tsx}'",
|
"format": "prettier --check --write '{src,__tests__}/**/*.{js,ts,tsx}'",
|
||||||
"version": "yarn test && yarn build",
|
"version": "yarn test && yarn build",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module.exports = function filterEmptyLines() {
|
export default function filterEmptyLines() {
|
||||||
const filterREG = /\s{2,}|\n/g;
|
const filterREG = /\s{2,}|\n/g;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -9,4 +9,4 @@ module.exports = function filterEmptyLines() {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ export interface AxiosRequestConfig {
|
||||||
adapter?: AxiosAdapter;
|
adapter?: AxiosAdapter;
|
||||||
baseURL?: string;
|
baseURL?: string;
|
||||||
cancelToken?: CancelToken;
|
cancelToken?: CancelToken;
|
||||||
data?: AxiosRequestData | AxiosRequestFormData;
|
data?: AxiosRequestData | AxiosRequestFormData | AxiosRequestFormData;
|
||||||
dataType?: 'json' | '其他';
|
dataType?: 'json' | '其他';
|
||||||
enableHttp2?: boolean;
|
enableHttp2?: boolean;
|
||||||
enableQuic?: boolean;
|
enableQuic?: boolean;
|
||||||
|
@ -59,7 +59,7 @@ export interface AxiosRequestConfig {
|
||||||
onDownloadProgress?: AxiosProgressCallback;
|
onDownloadProgress?: AxiosProgressCallback;
|
||||||
params?: AxiosRequestParams;
|
params?: AxiosRequestParams;
|
||||||
paramsSerializer?: (params?: AxiosRequestParams) => string;
|
paramsSerializer?: (params?: AxiosRequestParams) => string;
|
||||||
responseType?: 'text' | 'arraybuffer' | 'file';
|
responseType?: 'text' | 'arraybuffer';
|
||||||
sslVerify?: boolean;
|
sslVerify?: boolean;
|
||||||
transformRequest?: AxiosTransformer | AxiosTransformer[];
|
transformRequest?: AxiosTransformer | AxiosTransformer[];
|
||||||
transformResponse?: AxiosTransformer | AxiosTransformer[];
|
transformResponse?: AxiosTransformer | AxiosTransformer[];
|
||||||
|
@ -142,7 +142,7 @@ export default class Axios {
|
||||||
|
|
||||||
public get<TData = any>(
|
public get<TData = any>(
|
||||||
url: string,
|
url: string,
|
||||||
params?: AnyObject,
|
params?: AxiosRequestParams,
|
||||||
config?: AxiosRequestConfig,
|
config?: AxiosRequestConfig,
|
||||||
): Promise<AxiosResponse<TData>> {
|
): Promise<AxiosResponse<TData>> {
|
||||||
return this._requestMethodWithoutParams<TData>('get', url, params, config);
|
return this._requestMethodWithoutParams<TData>('get', url, params, config);
|
||||||
|
@ -150,7 +150,7 @@ export default class Axios {
|
||||||
|
|
||||||
public head<TData = any>(
|
public head<TData = any>(
|
||||||
url: string,
|
url: string,
|
||||||
params?: AnyObject,
|
params?: AxiosRequestParams,
|
||||||
config?: AxiosRequestConfig,
|
config?: AxiosRequestConfig,
|
||||||
): Promise<AxiosResponse<TData>> {
|
): Promise<AxiosResponse<TData>> {
|
||||||
return this._requestMethodWithoutParams<TData>('head', url, params, config);
|
return this._requestMethodWithoutParams<TData>('head', url, params, config);
|
||||||
|
@ -158,7 +158,7 @@ export default class Axios {
|
||||||
|
|
||||||
public post<TData = any>(
|
public post<TData = any>(
|
||||||
url: string,
|
url: string,
|
||||||
data?: AnyObject,
|
data?: AxiosRequestData | AxiosRequestFormData,
|
||||||
config?: AxiosRequestConfig,
|
config?: AxiosRequestConfig,
|
||||||
): Promise<AxiosResponse<TData>> {
|
): Promise<AxiosResponse<TData>> {
|
||||||
return this._requestMethodWithoutData<TData>('post', url, data, config);
|
return this._requestMethodWithoutData<TData>('post', url, data, config);
|
||||||
|
@ -166,7 +166,7 @@ export default class Axios {
|
||||||
|
|
||||||
public put<TData = any>(
|
public put<TData = any>(
|
||||||
url: string,
|
url: string,
|
||||||
data?: AnyObject,
|
data?: AxiosRequestData | AxiosRequestFormData,
|
||||||
config?: AxiosRequestConfig,
|
config?: AxiosRequestConfig,
|
||||||
): Promise<AxiosResponse<TData>> {
|
): Promise<AxiosResponse<TData>> {
|
||||||
return this._requestMethodWithoutData<TData>('put', url, data, config);
|
return this._requestMethodWithoutData<TData>('put', url, data, config);
|
||||||
|
@ -174,7 +174,7 @@ export default class Axios {
|
||||||
|
|
||||||
public delete<TData = any>(
|
public delete<TData = any>(
|
||||||
url: string,
|
url: string,
|
||||||
params?: AnyObject,
|
params?: AxiosRequestParams,
|
||||||
config?: AxiosRequestConfig,
|
config?: AxiosRequestConfig,
|
||||||
): Promise<AxiosResponse<TData>> {
|
): Promise<AxiosResponse<TData>> {
|
||||||
return this._requestMethodWithoutParams<TData>(
|
return this._requestMethodWithoutParams<TData>(
|
||||||
|
@ -212,11 +212,11 @@ export default class Axios {
|
||||||
private _requestMethodWithoutParams<TData = any>(
|
private _requestMethodWithoutParams<TData = any>(
|
||||||
method: AxiosRequestMethod,
|
method: AxiosRequestMethod,
|
||||||
url: string,
|
url: string,
|
||||||
params?: AnyObject,
|
params?: AxiosRequestParams,
|
||||||
config: AxiosRequestConfig = {},
|
config?: AxiosRequestConfig,
|
||||||
): Promise<AxiosResponse<TData>> {
|
): Promise<AxiosResponse<TData>> {
|
||||||
return this.request<TData>({
|
return this.request<TData>({
|
||||||
...config,
|
...(config ?? {}),
|
||||||
method,
|
method,
|
||||||
url,
|
url,
|
||||||
params,
|
params,
|
||||||
|
@ -226,11 +226,11 @@ export default class Axios {
|
||||||
private _requestMethodWithoutData<TData = any>(
|
private _requestMethodWithoutData<TData = any>(
|
||||||
method: AxiosRequestMethod,
|
method: AxiosRequestMethod,
|
||||||
url: string,
|
url: string,
|
||||||
data?: AnyObject,
|
data?: AxiosRequestData | AxiosRequestFormData,
|
||||||
config: AxiosRequestConfig = {},
|
config?: AxiosRequestConfig,
|
||||||
): Promise<AxiosResponse<TData>> {
|
): Promise<AxiosResponse<TData>> {
|
||||||
return this.request<TData>({
|
return this.request<TData>({
|
||||||
...config,
|
...(config ?? {}),
|
||||||
method,
|
method,
|
||||||
url,
|
url,
|
||||||
data,
|
data,
|
||||||
|
|
|
@ -207,8 +207,8 @@ export function createAdapter(platform: AxiosPlatform): AxiosAdapter {
|
||||||
filePath: config.params?.filePath,
|
filePath: config.params?.filePath,
|
||||||
fileName: config.params?.fileName,
|
fileName: config.params?.fileName,
|
||||||
success(response: any): void {
|
success(response: any): void {
|
||||||
transformCommon(response);
|
|
||||||
generateDownloadResponseData(response);
|
generateDownloadResponseData(response);
|
||||||
|
transformCommon(response);
|
||||||
config.success(response);
|
config.success(response);
|
||||||
},
|
},
|
||||||
fail(error: any): void {
|
fail(error: any): void {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { AxiosAdapterRequestConfig } from './adapter';
|
import { AxiosAdapterTask } from './adapter';
|
||||||
import { AxiosRequestConfig, AxiosResponse, AxiosResponseError } from './Axios';
|
import { AxiosRequestConfig, AxiosResponse, AxiosResponseError } from './Axios';
|
||||||
|
|
||||||
export type AxiosErrorResponse = AxiosResponse | AxiosResponseError;
|
export type AxiosErrorResponse = AxiosResponse | AxiosResponseError;
|
||||||
|
@ -8,14 +8,14 @@ class AxiosError extends Error {
|
||||||
|
|
||||||
public config: AxiosRequestConfig;
|
public config: AxiosRequestConfig;
|
||||||
|
|
||||||
public request: AxiosAdapterRequestConfig;
|
public request?: AxiosAdapterTask;
|
||||||
|
|
||||||
public response?: AxiosErrorResponse;
|
public response?: AxiosErrorResponse;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
message: string,
|
message: string,
|
||||||
config: AxiosRequestConfig,
|
config: AxiosRequestConfig,
|
||||||
request: AxiosAdapterRequestConfig,
|
request?: AxiosAdapterTask,
|
||||||
response?: AxiosErrorResponse,
|
response?: AxiosErrorResponse,
|
||||||
) {
|
) {
|
||||||
super(message);
|
super(message);
|
||||||
|
@ -31,7 +31,7 @@ class AxiosError extends Error {
|
||||||
export function createError(
|
export function createError(
|
||||||
message: string,
|
message: string,
|
||||||
config: AxiosRequestConfig,
|
config: AxiosRequestConfig,
|
||||||
request: AxiosAdapterRequestConfig,
|
request?: AxiosAdapterTask,
|
||||||
response?: AxiosErrorResponse,
|
response?: AxiosErrorResponse,
|
||||||
): AxiosError {
|
): AxiosError {
|
||||||
return new AxiosError(message, config, request, response);
|
return new AxiosError(message, config, request, response);
|
||||||
|
|
|
@ -1,42 +1,36 @@
|
||||||
import { isPlainObject, isString } from '../utils';
|
import { assert, isPlainObject, isString } from '../utils';
|
||||||
import { AdapterRequestType } from './adapter';
|
import { AdapterRequestType } from './adapter';
|
||||||
import { AxiosRequestConfig } from './Axios';
|
import { AxiosRequestConfig } from './Axios';
|
||||||
|
|
||||||
function isUpload(config: AxiosRequestConfig): boolean {
|
|
||||||
if (
|
|
||||||
!isString(config.method) ||
|
|
||||||
!isPlainObject(config.headers) ||
|
|
||||||
!isPlainObject(config.data)
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const method = config.method.toLowerCase();
|
|
||||||
const contentType =
|
|
||||||
config.headers['Content-Type'] ?? config.headers['content-type'];
|
|
||||||
|
|
||||||
return (
|
|
||||||
method === 'post' &&
|
|
||||||
/multipart\/form-data/.test(contentType) &&
|
|
||||||
isString(config.data.fileName) &&
|
|
||||||
isString(config.data.filePath)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function isDownload(config: AxiosRequestConfig): boolean {
|
|
||||||
const method = config.method?.toLowerCase() ?? 'get';
|
|
||||||
|
|
||||||
return method === 'get' && config.responseType === 'file';
|
|
||||||
}
|
|
||||||
|
|
||||||
export function generateType(config: AxiosRequestConfig): AdapterRequestType {
|
export function generateType(config: AxiosRequestConfig): AdapterRequestType {
|
||||||
let requestType: AdapterRequestType = 'request';
|
let requestType: AdapterRequestType = 'request';
|
||||||
|
|
||||||
if (isUpload(config)) {
|
if (
|
||||||
|
!isPlainObject(config.headers) ||
|
||||||
|
!/multipart\/form-data/.test(
|
||||||
|
config.headers['Content-Type'] ?? config.headers['content-type'] ?? '',
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return requestType;
|
||||||
|
}
|
||||||
|
|
||||||
|
const method = config.method?.toLowerCase() ?? 'get';
|
||||||
|
|
||||||
|
if (method === 'post') {
|
||||||
|
assert(isPlainObject(config.data), '上传文件时 data 需要是一个 object');
|
||||||
|
assert(
|
||||||
|
isString(config.data!.fileName),
|
||||||
|
'上传文件时 data.fileName 需要是一个 string',
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
isString(config.data!.filePath),
|
||||||
|
'上传文件时 data.filePath 需要是一个 string',
|
||||||
|
);
|
||||||
|
|
||||||
requestType = 'upload';
|
requestType = 'upload';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDownload(config)) {
|
if (method === 'get') {
|
||||||
requestType = 'download';
|
requestType = 'download';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
import { assert, isFunction, isPlainObject } from '../utils';
|
import { assert, isFunction, isPlainObject } from '../utils';
|
||||||
import { AxiosAdapterRequestConfig, AdapterRequestMethod } from './adapter';
|
import {
|
||||||
|
AxiosAdapterRequestConfig,
|
||||||
|
AdapterRequestMethod,
|
||||||
|
AxiosAdapterTask,
|
||||||
|
} from './adapter';
|
||||||
import { AxiosRequestConfig, AxiosResponse, AxiosResponseError } from './Axios';
|
import { AxiosRequestConfig, AxiosResponse, AxiosResponseError } from './Axios';
|
||||||
import { isCancelToken } from './cancel';
|
import { isCancelToken } from './cancel';
|
||||||
import { AxiosErrorResponse, createError } from './createError';
|
import { AxiosErrorResponse, createError } from './createError';
|
||||||
|
@ -30,9 +34,10 @@ export function request<TData = any>(
|
||||||
config: AxiosRequestConfig,
|
config: AxiosRequestConfig,
|
||||||
): Promise<AxiosResponse<TData>> {
|
): Promise<AxiosResponse<TData>> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
assert(isFunction(config.adapter), 'adapter 需要是一个 Function 类型');
|
assert(isFunction(config.adapter), 'adapter 需要是一个 function');
|
||||||
|
|
||||||
const adapterConfig: AxiosAdapterRequestConfig = Object.assign({}, config, {
|
const adapterConfig: AxiosAdapterRequestConfig = {
|
||||||
|
...config,
|
||||||
url: config.url ?? '',
|
url: config.url ?? '',
|
||||||
type: generateType(config),
|
type: generateType(config),
|
||||||
method: (config.method?.toUpperCase() as AdapterRequestMethod) ?? 'GET',
|
method: (config.method?.toUpperCase() as AdapterRequestMethod) ?? 'GET',
|
||||||
|
@ -49,14 +54,16 @@ export function request<TData = any>(
|
||||||
fail(error: AxiosResponseError): void {
|
fail(error: AxiosResponseError): void {
|
||||||
catchError('网络错误', error);
|
catchError('网络错误', error);
|
||||||
},
|
},
|
||||||
});
|
};
|
||||||
|
|
||||||
|
const adapterTask = config.adapter!(adapterConfig) as
|
||||||
|
| AxiosAdapterTask
|
||||||
|
| undefined;
|
||||||
|
|
||||||
function catchError(message: string, response?: AxiosErrorResponse): void {
|
function catchError(message: string, response?: AxiosErrorResponse): void {
|
||||||
reject(createError(message, config, adapterConfig, response));
|
reject(createError(message, config, adapterTask, response));
|
||||||
}
|
}
|
||||||
|
|
||||||
const adapterTask = config.adapter!(adapterConfig);
|
|
||||||
|
|
||||||
if (isPlainObject(adapterTask)) {
|
if (isPlainObject(adapterTask)) {
|
||||||
tryToggleProgressUpdate(adapterConfig, adapterTask.onProgressUpdate);
|
tryToggleProgressUpdate(adapterConfig, adapterTask.onProgressUpdate);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
import { buildURL, combineURL, dynamicURL, isAbsoluteURL } from '../utils';
|
import {
|
||||||
|
buildURL,
|
||||||
|
combineURL,
|
||||||
|
dynamicInterpolation,
|
||||||
|
isAbsoluteURL,
|
||||||
|
isDynamicURL,
|
||||||
|
} from '../utils';
|
||||||
import { AxiosRequestConfig } from './Axios';
|
import { AxiosRequestConfig } from './Axios';
|
||||||
|
|
||||||
export function transformURL(config: AxiosRequestConfig): string {
|
export function transformURL(config: AxiosRequestConfig): string {
|
||||||
|
@ -8,7 +14,11 @@ export function transformURL(config: AxiosRequestConfig): string {
|
||||||
url = combineURL(config.baseURL, url);
|
url = combineURL(config.baseURL, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
url = dynamicURL(url, config.params);
|
if (isDynamicURL(url)) {
|
||||||
|
const sourceData = Object.assign({}, config.params, config.data);
|
||||||
|
url = dynamicInterpolation(url, sourceData);
|
||||||
|
}
|
||||||
|
|
||||||
url = buildURL(url, config.params, config.paramsSerializer);
|
url = buildURL(url, config.params, config.paramsSerializer);
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
|
|
20
src/utils.ts
20
src/utils.ts
|
@ -1,5 +1,5 @@
|
||||||
import { AxiosPlatform } from './core/adapter';
|
import { AxiosPlatform } from './core/adapter';
|
||||||
import { AxiosRequestParams } from './core/Axios';
|
import { AxiosRequestData, AxiosRequestParams } from './core/Axios';
|
||||||
|
|
||||||
const _toString = Object.prototype.toString;
|
const _toString = Object.prototype.toString;
|
||||||
|
|
||||||
|
@ -184,25 +184,31 @@ export function buildURL(
|
||||||
return generateURL(url, paramsSerializer(params));
|
return generateURL(url, paramsSerializer(params));
|
||||||
}
|
}
|
||||||
|
|
||||||
const combineREG = /\/{2,}/g;
|
export const combineREG = /(?<!:)\/{2,}/g;
|
||||||
export function combineURL(baseURL = '', url: string): string {
|
export function combineURL(baseURL = '', url: string): string {
|
||||||
const separator = '/';
|
const separator = '/';
|
||||||
|
|
||||||
return `${baseURL}${separator}${url}`.replace(combineREG, separator);
|
return `${baseURL}${separator}${url}`.replace(combineREG, separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
const dynamicREG = /\/?(:([a-zA-Z_$][\w-$]*))\/??/g;
|
export const dynamicREG = /\/?(:([a-zA-Z_$][\w-$]*))\/??/g;
|
||||||
export function dynamicURL(url: string, params?: AxiosRequestParams): string {
|
export function isDynamicURL(url: string): boolean {
|
||||||
if (!isPlainObject(params)) {
|
return dynamicREG.test(url);
|
||||||
|
}
|
||||||
|
export function dynamicInterpolation(
|
||||||
|
url: string,
|
||||||
|
sourceData?: AxiosRequestParams & AxiosRequestData,
|
||||||
|
): string {
|
||||||
|
if (!isPlainObject(sourceData)) {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
return url.replace(dynamicREG, (key1, key2, key3) =>
|
return url.replace(dynamicREG, (key1, key2, key3) =>
|
||||||
key1.replace(key2, params[key3]),
|
key1.replace(key2, sourceData[key3]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const absoluteREG = /^([a-z][a-z\d+\-.]*:)?\/\//i;
|
export const absoluteREG = /^([a-z][a-z\d+\-.]*:)?\/\//i;
|
||||||
export function isAbsoluteURL(url: string): boolean {
|
export function isAbsoluteURL(url: string): boolean {
|
||||||
return absoluteREG.test(url);
|
return absoluteREG.test(url);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue