@whitesev/utils 2.3.0 → 2.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.amd.js +113 -61
- package/dist/index.amd.js.map +1 -1
- package/dist/index.cjs.js +113 -61
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +113 -61
- package/dist/index.esm.js.map +1 -1
- package/dist/index.iife.js +113 -61
- package/dist/index.iife.js.map +1 -1
- package/dist/index.system.js +113 -61
- package/dist/index.system.js.map +1 -1
- package/dist/index.umd.js +113 -61
- package/dist/index.umd.js.map +1 -1
- package/dist/types/src/Httpx.d.ts +1273 -1273
- package/dist/types/src/Log.d.ts +96 -96
- package/dist/types/src/Utils.d.ts +1761 -1752
- package/dist/types/src/VueObject.d.ts +110 -110
- package/package.json +1 -1
- package/src/Httpx.ts +114 -71
- package/src/Utils.ts +38 -10
|
@@ -1,110 +1,110 @@
|
|
|
1
|
-
export declare interface Vue2Object {
|
|
2
|
-
$attrs: any;
|
|
3
|
-
$children: Vue2Object[];
|
|
4
|
-
$createElement: (...args: any[]) => any;
|
|
5
|
-
$el: HTMLElement;
|
|
6
|
-
$listeners: any;
|
|
7
|
-
$options: any;
|
|
8
|
-
$parent: Vue2Object;
|
|
9
|
-
$refs: any;
|
|
10
|
-
$root: Vue2Object;
|
|
11
|
-
$scopedSlots: any;
|
|
12
|
-
$slots: any;
|
|
13
|
-
$store: any;
|
|
14
|
-
$vnode: any;
|
|
15
|
-
_data: any;
|
|
16
|
-
_directInactive: boolean;
|
|
17
|
-
_events: any;
|
|
18
|
-
_hasHookEvent: boolean;
|
|
19
|
-
_isBeingDestroyed: boolean;
|
|
20
|
-
_isDestroyed: boolean;
|
|
21
|
-
_isMounted: boolean;
|
|
22
|
-
_isVue: boolean;
|
|
23
|
-
$data: any;
|
|
24
|
-
$isServer: boolean;
|
|
25
|
-
$props: any;
|
|
26
|
-
$route: any & {
|
|
27
|
-
fullPath: string;
|
|
28
|
-
hash: string;
|
|
29
|
-
matched: any[];
|
|
30
|
-
meta: any;
|
|
31
|
-
name: string;
|
|
32
|
-
params: any;
|
|
33
|
-
path: string;
|
|
34
|
-
query: any;
|
|
35
|
-
};
|
|
36
|
-
$router: any & {
|
|
37
|
-
afterHooks: Function[];
|
|
38
|
-
app: Vue2Object;
|
|
39
|
-
apps: Vue2Object[];
|
|
40
|
-
beforeHooks: Function[];
|
|
41
|
-
fallback: boolean;
|
|
42
|
-
history: any & {
|
|
43
|
-
base: string;
|
|
44
|
-
current: any;
|
|
45
|
-
listeners: any[];
|
|
46
|
-
router: Vue2Object["$router"];
|
|
47
|
-
/**
|
|
48
|
-
*
|
|
49
|
-
* @param delta 访问的距离。如果 delta < 0 则后退相应数量的记录,如果 > 0 则前进。
|
|
50
|
-
* @param triggerListeners 是否应该触发连接到该历史的监听器
|
|
51
|
-
* @returns
|
|
52
|
-
*/
|
|
53
|
-
go: (delta: number, triggerListeners?: boolean) => void;
|
|
54
|
-
/**
|
|
55
|
-
*
|
|
56
|
-
* @param to 要设置的地址
|
|
57
|
-
* @param data 可选的 HistoryState 以关联该导航记录
|
|
58
|
-
* @returns
|
|
59
|
-
*/
|
|
60
|
-
push: (to: string, data?: any) => void;
|
|
61
|
-
/**
|
|
62
|
-
*
|
|
63
|
-
* @param to 要设置的地址
|
|
64
|
-
* @param data 可选的 HistoryState 以关联该导航记录
|
|
65
|
-
* @returns
|
|
66
|
-
*/
|
|
67
|
-
replace: (to: string, data?: any) => void;
|
|
68
|
-
};
|
|
69
|
-
matcher: any & {
|
|
70
|
-
addRoute: (...args: any[]) => any;
|
|
71
|
-
addRoutes: (...args: any[]) => any;
|
|
72
|
-
getRoutes: () => any;
|
|
73
|
-
match: (...args: any[]) => any;
|
|
74
|
-
};
|
|
75
|
-
mode: string;
|
|
76
|
-
resolveHooks: ((...args: any[]) => any)[];
|
|
77
|
-
currentRoute: any;
|
|
78
|
-
beforeEach: (callback: ((
|
|
79
|
-
/** 即将要进入的目标 路由对象 */
|
|
80
|
-
to: Vue2Object["$route"],
|
|
81
|
-
/** 当前导航正要离开的路由 */
|
|
82
|
-
from: Vue2Object["$route"],
|
|
83
|
-
/**
|
|
84
|
-
*
|
|
85
|
-
* + next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
|
|
86
|
-
* + next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
|
|
87
|
-
* + next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: 'home' 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
|
|
88
|
-
* + next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
|
|
89
|
-
*/
|
|
90
|
-
next: Function) => void)
|
|
91
|
-
/** 移除上一个添加的监听 */
|
|
92
|
-
| (() => void)) => void;
|
|
93
|
-
afterEach: (callback: ((
|
|
94
|
-
/** 即将要进入的目标 路由对象 */
|
|
95
|
-
to: Vue2Object["$route"],
|
|
96
|
-
/** 当前导航正要离开的路由 */
|
|
97
|
-
from: Vue2Object["$route"]) => void)
|
|
98
|
-
/** 移除上一个添加的监听 */
|
|
99
|
-
| (() => void)) => void;
|
|
100
|
-
};
|
|
101
|
-
$ssrContext: any;
|
|
102
|
-
$watch: (key: string | string[] | (() => any), handler: (this: any, newVal: any, oldVal: any) => void, options?: {
|
|
103
|
-
immediate?: boolean;
|
|
104
|
-
deep?: boolean;
|
|
105
|
-
}) => void;
|
|
106
|
-
[key: string]: any;
|
|
107
|
-
}
|
|
108
|
-
export declare interface HTMLVue2DivElement extends HTMLDivElement {
|
|
109
|
-
__vue__: Vue2Object;
|
|
110
|
-
}
|
|
1
|
+
export declare interface Vue2Object {
|
|
2
|
+
$attrs: any;
|
|
3
|
+
$children: Vue2Object[];
|
|
4
|
+
$createElement: (...args: any[]) => any;
|
|
5
|
+
$el: HTMLElement;
|
|
6
|
+
$listeners: any;
|
|
7
|
+
$options: any;
|
|
8
|
+
$parent: Vue2Object;
|
|
9
|
+
$refs: any;
|
|
10
|
+
$root: Vue2Object;
|
|
11
|
+
$scopedSlots: any;
|
|
12
|
+
$slots: any;
|
|
13
|
+
$store: any;
|
|
14
|
+
$vnode: any;
|
|
15
|
+
_data: any;
|
|
16
|
+
_directInactive: boolean;
|
|
17
|
+
_events: any;
|
|
18
|
+
_hasHookEvent: boolean;
|
|
19
|
+
_isBeingDestroyed: boolean;
|
|
20
|
+
_isDestroyed: boolean;
|
|
21
|
+
_isMounted: boolean;
|
|
22
|
+
_isVue: boolean;
|
|
23
|
+
$data: any;
|
|
24
|
+
$isServer: boolean;
|
|
25
|
+
$props: any;
|
|
26
|
+
$route: any & {
|
|
27
|
+
fullPath: string;
|
|
28
|
+
hash: string;
|
|
29
|
+
matched: any[];
|
|
30
|
+
meta: any;
|
|
31
|
+
name: string;
|
|
32
|
+
params: any;
|
|
33
|
+
path: string;
|
|
34
|
+
query: any;
|
|
35
|
+
};
|
|
36
|
+
$router: any & {
|
|
37
|
+
afterHooks: Function[];
|
|
38
|
+
app: Vue2Object;
|
|
39
|
+
apps: Vue2Object[];
|
|
40
|
+
beforeHooks: Function[];
|
|
41
|
+
fallback: boolean;
|
|
42
|
+
history: any & {
|
|
43
|
+
base: string;
|
|
44
|
+
current: any;
|
|
45
|
+
listeners: any[];
|
|
46
|
+
router: Vue2Object["$router"];
|
|
47
|
+
/**
|
|
48
|
+
*
|
|
49
|
+
* @param delta 访问的距离。如果 delta < 0 则后退相应数量的记录,如果 > 0 则前进。
|
|
50
|
+
* @param triggerListeners 是否应该触发连接到该历史的监听器
|
|
51
|
+
* @returns
|
|
52
|
+
*/
|
|
53
|
+
go: (delta: number, triggerListeners?: boolean) => void;
|
|
54
|
+
/**
|
|
55
|
+
*
|
|
56
|
+
* @param to 要设置的地址
|
|
57
|
+
* @param data 可选的 HistoryState 以关联该导航记录
|
|
58
|
+
* @returns
|
|
59
|
+
*/
|
|
60
|
+
push: (to: string, data?: any) => void;
|
|
61
|
+
/**
|
|
62
|
+
*
|
|
63
|
+
* @param to 要设置的地址
|
|
64
|
+
* @param data 可选的 HistoryState 以关联该导航记录
|
|
65
|
+
* @returns
|
|
66
|
+
*/
|
|
67
|
+
replace: (to: string, data?: any) => void;
|
|
68
|
+
};
|
|
69
|
+
matcher: any & {
|
|
70
|
+
addRoute: (...args: any[]) => any;
|
|
71
|
+
addRoutes: (...args: any[]) => any;
|
|
72
|
+
getRoutes: () => any;
|
|
73
|
+
match: (...args: any[]) => any;
|
|
74
|
+
};
|
|
75
|
+
mode: string;
|
|
76
|
+
resolveHooks: ((...args: any[]) => any)[];
|
|
77
|
+
currentRoute: any;
|
|
78
|
+
beforeEach: (callback: ((
|
|
79
|
+
/** 即将要进入的目标 路由对象 */
|
|
80
|
+
to: Vue2Object["$route"],
|
|
81
|
+
/** 当前导航正要离开的路由 */
|
|
82
|
+
from: Vue2Object["$route"],
|
|
83
|
+
/**
|
|
84
|
+
*
|
|
85
|
+
* + next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
|
|
86
|
+
* + next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
|
|
87
|
+
* + next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: 'home' 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
|
|
88
|
+
* + next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
|
|
89
|
+
*/
|
|
90
|
+
next: Function) => void)
|
|
91
|
+
/** 移除上一个添加的监听 */
|
|
92
|
+
| (() => void)) => void;
|
|
93
|
+
afterEach: (callback: ((
|
|
94
|
+
/** 即将要进入的目标 路由对象 */
|
|
95
|
+
to: Vue2Object["$route"],
|
|
96
|
+
/** 当前导航正要离开的路由 */
|
|
97
|
+
from: Vue2Object["$route"]) => void)
|
|
98
|
+
/** 移除上一个添加的监听 */
|
|
99
|
+
| (() => void)) => void;
|
|
100
|
+
};
|
|
101
|
+
$ssrContext: any;
|
|
102
|
+
$watch: (key: string | string[] | (() => any), handler: (this: any, newVal: any, oldVal: any) => void, options?: {
|
|
103
|
+
immediate?: boolean;
|
|
104
|
+
deep?: boolean;
|
|
105
|
+
}) => void;
|
|
106
|
+
[key: string]: any;
|
|
107
|
+
}
|
|
108
|
+
export declare interface HTMLVue2DivElement extends HTMLDivElement {
|
|
109
|
+
__vue__: Vue2Object;
|
|
110
|
+
}
|
package/package.json
CHANGED
package/src/Httpx.ts
CHANGED
|
@@ -1299,7 +1299,7 @@ class Httpx {
|
|
|
1299
1299
|
return uuid;
|
|
1300
1300
|
} else {
|
|
1301
1301
|
console.warn(
|
|
1302
|
-
"HttpxRequestHook.addBeforeRequestCallBack
|
|
1302
|
+
"[Httpx-HttpxRequestHook.addBeforeRequestCallBack] fn is not a function"
|
|
1303
1303
|
);
|
|
1304
1304
|
}
|
|
1305
1305
|
},
|
|
@@ -1889,66 +1889,93 @@ class Httpx {
|
|
|
1889
1889
|
argumentsList: any
|
|
1890
1890
|
) {
|
|
1891
1891
|
/* X浏览器会因为设置了responseType导致不返回responseText */
|
|
1892
|
-
let
|
|
1892
|
+
let originResponse: HttpxAsyncResultData<HttpxDetails> = argumentsList[0];
|
|
1893
1893
|
/* responseText为空,response不为空的情况 */
|
|
1894
1894
|
if (
|
|
1895
|
-
Utils.isNull(
|
|
1896
|
-
Utils.isNotNull(
|
|
1895
|
+
Utils.isNull(originResponse["responseText"]) &&
|
|
1896
|
+
Utils.isNotNull(originResponse["response"])
|
|
1897
1897
|
) {
|
|
1898
|
-
if (typeof
|
|
1898
|
+
if (typeof originResponse["response"] === "object") {
|
|
1899
1899
|
Utils.tryCatch().run(() => {
|
|
1900
|
-
|
|
1900
|
+
originResponse["responseText"] = JSON.stringify(
|
|
1901
|
+
originResponse["response"]
|
|
1902
|
+
);
|
|
1901
1903
|
});
|
|
1902
1904
|
} else {
|
|
1903
|
-
|
|
1905
|
+
originResponse["responseText"] = originResponse["response"];
|
|
1904
1906
|
}
|
|
1905
1907
|
}
|
|
1906
1908
|
|
|
1907
1909
|
/* response为空,responseText不为空的情况 */
|
|
1908
1910
|
if (
|
|
1909
|
-
|
|
1910
|
-
typeof
|
|
1911
|
-
|
|
1911
|
+
originResponse["response"] == null &&
|
|
1912
|
+
typeof originResponse["responseText"] === "string" &&
|
|
1913
|
+
originResponse["responseText"].trim() !== ""
|
|
1912
1914
|
) {
|
|
1913
|
-
|
|
1915
|
+
/** 原始的请求text */
|
|
1916
|
+
let httpxResponseText = originResponse.responseText;
|
|
1917
|
+
// 自定义个新的response
|
|
1918
|
+
let httpxResponse: any = httpxResponseText;
|
|
1914
1919
|
if (details.responseType === "json") {
|
|
1915
|
-
|
|
1920
|
+
httpxResponse = Utils.toJSON(httpxResponseText);
|
|
1916
1921
|
} else if (details.responseType === "document") {
|
|
1917
1922
|
let parser = new DOMParser();
|
|
1918
|
-
|
|
1919
|
-
|
|
1923
|
+
httpxResponse = parser.parseFromString(
|
|
1924
|
+
httpxResponseText,
|
|
1920
1925
|
"text/html"
|
|
1921
1926
|
);
|
|
1922
1927
|
} else if (details.responseType === "arraybuffer") {
|
|
1923
1928
|
let encoder = new TextEncoder();
|
|
1924
|
-
let arrayBuffer = encoder.encode(
|
|
1925
|
-
|
|
1929
|
+
let arrayBuffer = encoder.encode(httpxResponseText);
|
|
1930
|
+
httpxResponse = arrayBuffer;
|
|
1926
1931
|
} else if (details.responseType === "blob") {
|
|
1927
1932
|
let encoder = new TextEncoder();
|
|
1928
|
-
let arrayBuffer = encoder.encode(
|
|
1929
|
-
|
|
1930
|
-
} else {
|
|
1931
|
-
newResponse = Response["responseText"];
|
|
1933
|
+
let arrayBuffer = encoder.encode(httpxResponseText);
|
|
1934
|
+
httpxResponse = new Blob([arrayBuffer]);
|
|
1932
1935
|
}
|
|
1936
|
+
// 尝试覆盖原response
|
|
1933
1937
|
try {
|
|
1934
|
-
|
|
1938
|
+
let setStatus = Reflect.set(
|
|
1939
|
+
originResponse,
|
|
1940
|
+
"response",
|
|
1941
|
+
httpxResponse
|
|
1942
|
+
);
|
|
1943
|
+
if (!setStatus) {
|
|
1944
|
+
console.warn(
|
|
1945
|
+
"[Httpx-HttpxCallBack.oonLoad] 覆盖原始 response 失败,尝试添加新的httpxResponse"
|
|
1946
|
+
);
|
|
1947
|
+
try {
|
|
1948
|
+
Reflect.set(originResponse, "httpxResponse", httpxResponse);
|
|
1949
|
+
} catch (error) {
|
|
1950
|
+
console.warn(
|
|
1951
|
+
"[Httpx-HttpxCallBack.oonLoad] httpxResponse 无法被覆盖"
|
|
1952
|
+
);
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1935
1955
|
} catch (error) {
|
|
1936
|
-
console.warn(
|
|
1956
|
+
console.warn(
|
|
1957
|
+
"[Httpx-HttpxCallBack.oonLoad] 原始 response 无法被覆盖,尝试添加新的httpxResponse"
|
|
1958
|
+
);
|
|
1959
|
+
try {
|
|
1960
|
+
Reflect.set(originResponse, "httpxResponse", httpxResponse);
|
|
1961
|
+
} catch (error) {
|
|
1962
|
+
console.warn(
|
|
1963
|
+
"[Httpx-HttpxCallBack.oonLoad] httpxResponse 无法被覆盖"
|
|
1964
|
+
);
|
|
1965
|
+
}
|
|
1937
1966
|
}
|
|
1938
1967
|
}
|
|
1939
1968
|
/* Stay扩展中没有finalUrl,对应的是responseURL */
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
(
|
|
1943
|
-
) {
|
|
1944
|
-
Response["finalUrl"] = (Response as any)["responseURL"];
|
|
1969
|
+
let originResponseURL = Reflect.get(originResponse, "responseURL");
|
|
1970
|
+
if (originResponse["finalUrl"] == null && originResponseURL != null) {
|
|
1971
|
+
Reflect.set(originResponse, "finalUrl", originResponseURL);
|
|
1945
1972
|
}
|
|
1946
1973
|
|
|
1947
1974
|
/* 状态码2xx都是成功的 */
|
|
1948
|
-
if (Math.floor(
|
|
1975
|
+
if (Math.floor(originResponse.status / 100) === 2) {
|
|
1949
1976
|
if (
|
|
1950
1977
|
this.context.HttpxResponseHook.successResponseCallBack(
|
|
1951
|
-
|
|
1978
|
+
originResponse,
|
|
1952
1979
|
details
|
|
1953
1980
|
) == null
|
|
1954
1981
|
) {
|
|
@@ -1957,7 +1984,7 @@ class Httpx {
|
|
|
1957
1984
|
}
|
|
1958
1985
|
resolve({
|
|
1959
1986
|
status: true,
|
|
1960
|
-
data:
|
|
1987
|
+
data: originResponse,
|
|
1961
1988
|
details: details,
|
|
1962
1989
|
msg: "请求完毕",
|
|
1963
1990
|
type: "onload",
|
|
@@ -2007,7 +2034,7 @@ class Httpx {
|
|
|
2007
2034
|
*/
|
|
2008
2035
|
request(details: Required<HttpxDetails>) {
|
|
2009
2036
|
if (this.context.#LOG_DETAILS) {
|
|
2010
|
-
console.log("Httpx
|
|
2037
|
+
console.log("[Httpx-HttpxRequest.request] 请求前的配置👇", details);
|
|
2011
2038
|
}
|
|
2012
2039
|
if (
|
|
2013
2040
|
typeof this.context.HttpxRequestHook.beforeRequestCallBack ===
|
|
@@ -2047,37 +2074,43 @@ class Httpx {
|
|
|
2047
2074
|
abortController: AbortController
|
|
2048
2075
|
) {
|
|
2049
2076
|
fetch(details.url, fetchRequestInit)
|
|
2050
|
-
.then(async (
|
|
2051
|
-
/**
|
|
2052
|
-
|
|
2053
|
-
*/
|
|
2054
|
-
let httpxResponse = {
|
|
2077
|
+
.then(async (fetchResponse) => {
|
|
2078
|
+
/** 自定义的response */
|
|
2079
|
+
let httpxResponse: HttpxAsyncResultData = {
|
|
2055
2080
|
isFetch: true,
|
|
2056
|
-
finalUrl:
|
|
2081
|
+
finalUrl: fetchResponse.url,
|
|
2057
2082
|
readyState: 4,
|
|
2058
|
-
|
|
2059
|
-
|
|
2083
|
+
// @ts-ignore
|
|
2084
|
+
status: fetchResponse.status,
|
|
2085
|
+
statusText: fetchResponse.statusText,
|
|
2060
2086
|
response: void 0,
|
|
2061
|
-
responseFetchHeaders:
|
|
2087
|
+
responseFetchHeaders: fetchResponse.headers,
|
|
2062
2088
|
responseHeaders: "",
|
|
2089
|
+
// @ts-ignore
|
|
2063
2090
|
responseText: void 0,
|
|
2064
2091
|
responseType: details.responseType,
|
|
2065
2092
|
responseXML: void 0,
|
|
2066
2093
|
};
|
|
2067
2094
|
Object.assign(httpxResponse, details.context || {});
|
|
2068
2095
|
|
|
2069
|
-
|
|
2096
|
+
// 把headers转为字符串
|
|
2097
|
+
for (const [key, value] of (fetchResponse.headers as any).entries()) {
|
|
2070
2098
|
httpxResponse.responseHeaders += `${key}: ${value}\n`;
|
|
2071
2099
|
}
|
|
2072
2100
|
|
|
2073
|
-
|
|
2101
|
+
/** 请求返回的类型 */
|
|
2102
|
+
const fetchResponseType = fetchResponse.headers.get("Content-Type");
|
|
2103
|
+
|
|
2104
|
+
/* 如果需要stream,且获取到的是stream,那直接返回 */
|
|
2074
2105
|
if (
|
|
2075
2106
|
details.responseType === "stream" ||
|
|
2076
|
-
(
|
|
2077
|
-
|
|
2107
|
+
(fetchResponse.headers.has("Content-Type") &&
|
|
2108
|
+
fetchResponse.headers
|
|
2109
|
+
.get("Content-Type")!
|
|
2110
|
+
.includes("text/event-stream"))
|
|
2078
2111
|
) {
|
|
2079
|
-
(httpxResponse
|
|
2080
|
-
(httpxResponse
|
|
2112
|
+
Reflect.set(httpxResponse, "isStream", true);
|
|
2113
|
+
Reflect.set(httpxResponse, "response", fetchResponse.body);
|
|
2081
2114
|
Reflect.deleteProperty(httpxResponse, "responseText");
|
|
2082
2115
|
Reflect.deleteProperty(httpxResponse, "responseXML");
|
|
2083
2116
|
details.onload(httpxResponse);
|
|
@@ -2085,57 +2118,67 @@ class Httpx {
|
|
|
2085
2118
|
}
|
|
2086
2119
|
|
|
2087
2120
|
/** 响应 */
|
|
2088
|
-
let response = "";
|
|
2121
|
+
let response: any = "";
|
|
2089
2122
|
/** 响应字符串 */
|
|
2090
2123
|
let responseText = "";
|
|
2091
2124
|
/** 响应xml文档 */
|
|
2092
|
-
let responseXML = "";
|
|
2093
|
-
|
|
2094
|
-
let arrayBuffer = await
|
|
2125
|
+
let responseXML: XMLDocument | string = "";
|
|
2126
|
+
/** 先获取二进制数据 */
|
|
2127
|
+
let arrayBuffer = await fetchResponse.arrayBuffer();
|
|
2095
2128
|
|
|
2129
|
+
/** 数据编码 */
|
|
2096
2130
|
let encoding = "utf-8";
|
|
2097
|
-
if (
|
|
2098
|
-
let charsetMatched =
|
|
2131
|
+
if (fetchResponse.headers.has("Content-Type")) {
|
|
2132
|
+
let charsetMatched = fetchResponse.headers
|
|
2099
2133
|
.get("Content-Type")
|
|
2100
2134
|
?.match(/charset=(.+)/);
|
|
2101
2135
|
if (charsetMatched) {
|
|
2102
2136
|
encoding = charsetMatched[1];
|
|
2137
|
+
encoding = encoding.toLowerCase();
|
|
2103
2138
|
}
|
|
2104
2139
|
}
|
|
2140
|
+
// Failed to construct 'TextDecoder': The encoding label provided ('"UTF-8"') is invalid.
|
|
2141
|
+
// 去除引号
|
|
2142
|
+
encoding = encoding.replace(/('|")/gi, "");
|
|
2143
|
+
// 编码
|
|
2105
2144
|
let textDecoder = new TextDecoder(encoding);
|
|
2106
2145
|
responseText = textDecoder.decode(arrayBuffer);
|
|
2107
2146
|
response = responseText;
|
|
2108
2147
|
|
|
2109
2148
|
if (details.responseType === "arraybuffer") {
|
|
2110
|
-
|
|
2149
|
+
// response返回格式是二进制流
|
|
2150
|
+
response = arrayBuffer;
|
|
2111
2151
|
} else if (details.responseType === "blob") {
|
|
2112
|
-
|
|
2152
|
+
// response返回格式是blob
|
|
2153
|
+
response = new Blob([arrayBuffer]);
|
|
2154
|
+
} else if (
|
|
2155
|
+
details.responseType === "json" ||
|
|
2156
|
+
(typeof fetchResponseType === "string" &&
|
|
2157
|
+
fetchResponseType.includes("application/json"))
|
|
2158
|
+
) {
|
|
2159
|
+
// response返回格式是JSON格式
|
|
2160
|
+
response = Utils.toJSON(responseText);
|
|
2113
2161
|
} else if (
|
|
2114
2162
|
details.responseType === "document" ||
|
|
2115
2163
|
details.responseType == null
|
|
2116
2164
|
) {
|
|
2165
|
+
// response返回格式是文档格式
|
|
2117
2166
|
let parser = new DOMParser();
|
|
2118
|
-
|
|
2119
|
-
responseText,
|
|
2120
|
-
"text/html"
|
|
2121
|
-
);
|
|
2122
|
-
} else if (details.responseType === "json") {
|
|
2123
|
-
(response as any) = Utils.toJSON(responseText);
|
|
2167
|
+
response = parser.parseFromString(responseText, "text/html");
|
|
2124
2168
|
}
|
|
2169
|
+
// 转为XML结构
|
|
2125
2170
|
let parser = new DOMParser();
|
|
2126
|
-
|
|
2127
|
-
responseText,
|
|
2128
|
-
"text/xml"
|
|
2129
|
-
);
|
|
2171
|
+
responseXML = parser.parseFromString(responseText, "text/xml");
|
|
2130
2172
|
|
|
2131
|
-
(httpxResponse
|
|
2132
|
-
(httpxResponse
|
|
2133
|
-
(httpxResponse
|
|
2173
|
+
Reflect.set(httpxResponse, "response", response);
|
|
2174
|
+
Reflect.set(httpxResponse, "responseText", responseText);
|
|
2175
|
+
Reflect.set(httpxResponse, "responseXML", responseXML);
|
|
2134
2176
|
|
|
2177
|
+
// 执行回调
|
|
2135
2178
|
details.onload(httpxResponse);
|
|
2136
2179
|
})
|
|
2137
|
-
.catch((
|
|
2138
|
-
if (
|
|
2180
|
+
.catch((error: any) => {
|
|
2181
|
+
if (error.name === "AbortError") {
|
|
2139
2182
|
return;
|
|
2140
2183
|
}
|
|
2141
2184
|
details.onerror({
|
|
@@ -2146,7 +2189,7 @@ class Httpx {
|
|
|
2146
2189
|
statusText: "",
|
|
2147
2190
|
responseHeaders: "",
|
|
2148
2191
|
responseText: "",
|
|
2149
|
-
error:
|
|
2192
|
+
error: error,
|
|
2150
2193
|
});
|
|
2151
2194
|
});
|
|
2152
2195
|
details.onloadstart({
|
|
@@ -2210,7 +2253,7 @@ class Httpx {
|
|
|
2210
2253
|
constructor(__xmlHttpRequest__?: any) {
|
|
2211
2254
|
if (typeof __xmlHttpRequest__ !== "function") {
|
|
2212
2255
|
console.warn(
|
|
2213
|
-
"Httpx未传入GM_xmlhttpRequest函数或传入的GM_xmlhttpRequest不是Function
|
|
2256
|
+
"[Httpx-constructor] 未传入GM_xmlhttpRequest函数或传入的GM_xmlhttpRequest不是Function,将默认使用window.fetch"
|
|
2214
2257
|
);
|
|
2215
2258
|
}
|
|
2216
2259
|
this.interceptors.request.context = this as any;
|
package/src/Utils.ts
CHANGED
|
@@ -3951,20 +3951,48 @@ class Utils {
|
|
|
3951
3951
|
compareArrayData?: TT[],
|
|
3952
3952
|
compareFun?: (item1: T, item2: TT) => boolean
|
|
3953
3953
|
): any[];
|
|
3954
|
-
|
|
3954
|
+
/**
|
|
3955
|
+
* 数组去重,去除不需要的值
|
|
3956
|
+
* @param uniqueArrayData 需要过滤的数组
|
|
3957
|
+
* @param getIdentfierValue 获取用于确定唯一性的值
|
|
3958
|
+
* @example
|
|
3959
|
+
* Utils.uniqueArray([{name:"1",host:"baidu.com"},{name:"2",host:"baidu.com"},{name:"3",host:"baidu.com"}]);
|
|
3960
|
+
* > [{name:"1",host:"baidu.com"}]
|
|
3961
|
+
*/
|
|
3962
|
+
uniqueArray<T>(
|
|
3963
|
+
uniqueArrayData: T[],
|
|
3964
|
+
getIdentfierValue: (itemValue: T) => any
|
|
3965
|
+
): T[];
|
|
3966
|
+
uniqueArray<T, T2>(
|
|
3955
3967
|
uniqueArrayData: T[] = [],
|
|
3956
|
-
compareArrayData:
|
|
3957
|
-
compareFun: (
|
|
3958
|
-
// @ts-ignore
|
|
3968
|
+
compareArrayData: any,
|
|
3969
|
+
compareFun: any = (item: any, item2: any) => {
|
|
3959
3970
|
return item === item2;
|
|
3960
3971
|
}
|
|
3961
3972
|
): any[] {
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3973
|
+
if (typeof compareArrayData === "function") {
|
|
3974
|
+
const compareFn = compareArrayData;
|
|
3975
|
+
const seen = new Set();
|
|
3976
|
+
|
|
3977
|
+
const result: T[] = [];
|
|
3978
|
+
for (const item of uniqueArrayData) {
|
|
3979
|
+
// 使用compareFn函数来获取当前对象的唯一标识
|
|
3980
|
+
const identfier = compareFn(item);
|
|
3981
|
+
// 如果Set中还没有这个标识,则添加到结果数组中,并将其标识存入Set
|
|
3982
|
+
if (!seen.has(identfier)) {
|
|
3983
|
+
seen.add(identfier);
|
|
3984
|
+
result.push(item);
|
|
3985
|
+
}
|
|
3986
|
+
}
|
|
3987
|
+
return result;
|
|
3988
|
+
} else {
|
|
3989
|
+
return Array.from(uniqueArrayData).filter(
|
|
3990
|
+
(item) =>
|
|
3991
|
+
!Array.from(compareArrayData).some(function (item2) {
|
|
3992
|
+
return compareFun(item, item2);
|
|
3993
|
+
})
|
|
3994
|
+
);
|
|
3995
|
+
}
|
|
3968
3996
|
}
|
|
3969
3997
|
/**
|
|
3970
3998
|
* 等待函数数组全部执行完毕,注意,每个函数的顺序不是同步
|