@whitesev/utils 1.0.0
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/README.md +172 -0
- package/dist/index.cjs.js +6017 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +6015 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.umd.js +6023 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/src/ColorConversion.d.ts +45 -0
- package/dist/src/Dictionary.d.ts +87 -0
- package/dist/src/GBKEncoder.d.ts +17 -0
- package/dist/src/Hooks.d.ts +5 -0
- package/dist/src/Httpx.d.ts +50 -0
- package/dist/src/LockFunction.d.ts +16 -0
- package/dist/src/Log.d.ts +66 -0
- package/dist/src/Progress.d.ts +6 -0
- package/dist/src/Utils.d.ts +1560 -0
- package/dist/src/UtilsCore.d.ts +9 -0
- package/dist/src/UtilsGMCookie.d.ts +36 -0
- package/dist/src/UtilsGMMenu.d.ts +119 -0
- package/dist/src/ajaxHooker.d.ts +6 -0
- package/dist/src/indexedDB.d.ts +165 -0
- package/dist/src/tryCatch.d.ts +31 -0
- package/index.ts +3 -0
- package/package.json +34 -0
- package/rollup.config.js +28 -0
- package/src/ColorConversion.ts +124 -0
- package/src/Dictionary.ts +158 -0
- package/src/GBKEncoder.js +111 -0
- package/src/GBKEncoder.ts +116 -0
- package/src/Hooks.js +73 -0
- package/src/Httpx.js +747 -0
- package/src/LockFunction.js +35 -0
- package/src/Log.js +256 -0
- package/src/Progress.js +98 -0
- package/src/Utils.ts +4495 -0
- package/src/UtilsCore.ts +39 -0
- package/src/UtilsGMCookie.ts +167 -0
- package/src/UtilsGMMenu.js +464 -0
- package/src/ajaxHooker.js +560 -0
- package/src/indexedDB.js +355 -0
- package/src/tryCatch.js +100 -0
- package/src/types/AjaxHooker.d.ts +153 -0
- package/src/types/DOMUtils.d.ts +188 -0
- package/src/types/Hook.d.ts +16 -0
- package/src/types/Httpx.d.ts +1308 -0
- package/src/types/Indexdb.d.ts +128 -0
- package/src/types/LockFunction.d.ts +47 -0
- package/src/types/Log.d.ts +91 -0
- package/src/types/Progress.d.ts +30 -0
- package/src/types/TryCatch.d.ts +6 -0
- package/src/types/UtilsCore.d.ts +7 -0
- package/src/types/UtilsGMMenu.d.ts +224 -0
- package/src/types/global.d.ts +58 -0
- package/tsconfig.json +32 -0
package/src/Httpx.js
ADDED
|
@@ -0,0 +1,747 @@
|
|
|
1
|
+
const Httpx = function (__xmlHttpRequest__) {
|
|
2
|
+
if (typeof __xmlHttpRequest__ !== "function") {
|
|
3
|
+
console.warn("Httpx未传入GM_xmlhttpRequest函数,强制默认使用fetch");
|
|
4
|
+
}
|
|
5
|
+
const GM_Api = {
|
|
6
|
+
/**
|
|
7
|
+
* @type {GM_xmlhttpRequest}
|
|
8
|
+
*/
|
|
9
|
+
xmlHttpRequest: __xmlHttpRequest__,
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* @type {HttpxDetails}
|
|
13
|
+
*/
|
|
14
|
+
let defaultDetails = {
|
|
15
|
+
url: void 0,
|
|
16
|
+
timeout: 5000,
|
|
17
|
+
async: false,
|
|
18
|
+
responseType: void 0,
|
|
19
|
+
headers: void 0,
|
|
20
|
+
data: void 0,
|
|
21
|
+
redirect: void 0,
|
|
22
|
+
cookie: void 0,
|
|
23
|
+
binary: void 0,
|
|
24
|
+
nocache: void 0,
|
|
25
|
+
revalidate: void 0,
|
|
26
|
+
context: void 0,
|
|
27
|
+
overrideMimeType: void 0,
|
|
28
|
+
anonymous: void 0,
|
|
29
|
+
fetch: void 0,
|
|
30
|
+
fetchInit: void 0,
|
|
31
|
+
user: void 0,
|
|
32
|
+
password: void 0,
|
|
33
|
+
onabort() {},
|
|
34
|
+
onerror() {},
|
|
35
|
+
ontimeout() {},
|
|
36
|
+
onloadstart() {},
|
|
37
|
+
onreadystatechange() {},
|
|
38
|
+
onprogress() {},
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* 输出请求配置
|
|
42
|
+
*/
|
|
43
|
+
let LOG_DETAILS = false;
|
|
44
|
+
|
|
45
|
+
const HttpxRequestHook = {
|
|
46
|
+
/**
|
|
47
|
+
* 发送请求前的回调
|
|
48
|
+
* 如果返回false则阻止本次返回
|
|
49
|
+
* @param {HttpxDetails} details 当前的请求配置
|
|
50
|
+
*/
|
|
51
|
+
beforeRequestCallBack(details) {},
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const HttpxRequestDetails = {
|
|
55
|
+
/**
|
|
56
|
+
* 获取请求配置
|
|
57
|
+
* @param {HttpxMethod} method 当前请求方法,默认get
|
|
58
|
+
* @param {(...args: any[])=>void} resolve promise回调
|
|
59
|
+
* @param {HttpxDetails} details 请求配置
|
|
60
|
+
* @returns
|
|
61
|
+
*/
|
|
62
|
+
getDetails(method, resolve, details) {
|
|
63
|
+
/**
|
|
64
|
+
* @type {HttpxDetails}
|
|
65
|
+
*/
|
|
66
|
+
let result = {
|
|
67
|
+
url: details.url || defaultDetails.url,
|
|
68
|
+
method: (method || "GET").toString().toUpperCase(),
|
|
69
|
+
timeout: details.timeout || defaultDetails.timeout,
|
|
70
|
+
responseType: details.responseType || defaultDetails.responseType,
|
|
71
|
+
/* 对象使用深拷贝 */
|
|
72
|
+
headers: Utils.deepClone(defaultDetails.headers),
|
|
73
|
+
data: details.data || defaultDetails.data,
|
|
74
|
+
redirect: details.redirect || defaultDetails.redirect,
|
|
75
|
+
cookie: details.cookie || defaultDetails.cookie,
|
|
76
|
+
binary: details.binary || defaultDetails.binary,
|
|
77
|
+
nocache: details.nocache || defaultDetails.nocache,
|
|
78
|
+
revalidate: details.revalidate || defaultDetails.revalidate,
|
|
79
|
+
/* 对象使用深拷贝 */
|
|
80
|
+
context: Utils.deepClone(details.context || defaultDetails.context),
|
|
81
|
+
overrideMimeType:
|
|
82
|
+
details.overrideMimeType || defaultDetails.overrideMimeType,
|
|
83
|
+
anonymous: details.anonymous || defaultDetails.anonymous,
|
|
84
|
+
fetch: details.fetch || defaultDetails.fetch,
|
|
85
|
+
/* 对象使用深拷贝 */
|
|
86
|
+
fetchInit: Utils.deepClone(defaultDetails.fetchInit),
|
|
87
|
+
user: details.user || defaultDetails.user,
|
|
88
|
+
password: details.password || defaultDetails.password,
|
|
89
|
+
onabort(...args) {
|
|
90
|
+
HttpxCallBack.onAbort(details, resolve, args);
|
|
91
|
+
},
|
|
92
|
+
onerror(...args) {
|
|
93
|
+
HttpxCallBack.onError(details, resolve, args);
|
|
94
|
+
},
|
|
95
|
+
onloadstart(...args) {
|
|
96
|
+
HttpxCallBack.onLoadStart(details, args);
|
|
97
|
+
},
|
|
98
|
+
onprogress(...args) {
|
|
99
|
+
HttpxCallBack.onProgress(details, args);
|
|
100
|
+
},
|
|
101
|
+
onreadystatechange(...args) {
|
|
102
|
+
HttpxCallBack.onReadyStateChange(details, args);
|
|
103
|
+
},
|
|
104
|
+
ontimeout(...args) {
|
|
105
|
+
HttpxCallBack.onTimeout(details, resolve, args);
|
|
106
|
+
},
|
|
107
|
+
onload(...args) {
|
|
108
|
+
HttpxCallBack.onLoad(details, resolve, args);
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
if (typeof GM_Api.xmlHttpRequest !== "function") {
|
|
112
|
+
result.fetch = true;
|
|
113
|
+
}
|
|
114
|
+
if (typeof result.headers === "object") {
|
|
115
|
+
if (typeof details.headers === "object") {
|
|
116
|
+
Object.keys(details.headers).forEach((keyName, index) => {
|
|
117
|
+
if (keyName in result.headers && details.headers[keyName] == null) {
|
|
118
|
+
/* 在默认的header中存在,且设置它新的值为空,那么就是默认的值 */
|
|
119
|
+
Reflect.deleteProperty(result.headers, keyName);
|
|
120
|
+
} else {
|
|
121
|
+
result.headers[keyName] = details.headers[keyName];
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
} else {
|
|
125
|
+
/* details.headers为空 */
|
|
126
|
+
/* 不做处理 */
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
result.headers = details.headers;
|
|
130
|
+
}
|
|
131
|
+
if (typeof result.fetchInit === "object") {
|
|
132
|
+
/* 使用assign替换且添加 */
|
|
133
|
+
if (typeof details.fetchInit === "object") {
|
|
134
|
+
Object.keys(details.fetchInit).forEach((keyName, index) => {
|
|
135
|
+
if (
|
|
136
|
+
keyName in result.fetchInit &&
|
|
137
|
+
details.fetchInit[keyName] == null
|
|
138
|
+
) {
|
|
139
|
+
/* 在默认的fetchInit中存在,且设置它新的值为空,那么就是默认的值 */
|
|
140
|
+
Reflect.deleteProperty(result.fetchInit, keyName);
|
|
141
|
+
} else {
|
|
142
|
+
result.fetchInit[keyName] = details.fetchInit[keyName];
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
} else {
|
|
147
|
+
result.fetchInit = details.fetchInit;
|
|
148
|
+
}
|
|
149
|
+
return result;
|
|
150
|
+
},
|
|
151
|
+
/**
|
|
152
|
+
* 处理发送请求的details,去除值为undefined、空function的值
|
|
153
|
+
* @param {HttpxDetails} details
|
|
154
|
+
* @returns {HttpxDetails}
|
|
155
|
+
*/
|
|
156
|
+
handle(details) {
|
|
157
|
+
Object.keys(details).forEach((keyName) => {
|
|
158
|
+
if (
|
|
159
|
+
details[keyName] == null ||
|
|
160
|
+
(details[keyName] instanceof Function &&
|
|
161
|
+
Utils.isNull(details[keyName]))
|
|
162
|
+
) {
|
|
163
|
+
Reflect.deleteProperty(details, keyName);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
if (Utils.isNull(details.url)) {
|
|
168
|
+
throw new TypeError(`Utils.Httpx 参数 url不符合要求: ${details.url}`);
|
|
169
|
+
}
|
|
170
|
+
/* method值统一大写,兼容Via */
|
|
171
|
+
details.method = details.method.toUpperCase();
|
|
172
|
+
/* 判断是否是以http开头,否则主动加上origin */
|
|
173
|
+
try {
|
|
174
|
+
new URL(details.url);
|
|
175
|
+
} catch (error) {
|
|
176
|
+
if (details.url.startsWith("//")) {
|
|
177
|
+
details.url = globalThis.location.protocol + details.url;
|
|
178
|
+
} else if (details.url.startsWith("/")) {
|
|
179
|
+
details.url = globalThis.location.origin + details.url;
|
|
180
|
+
} else {
|
|
181
|
+
details.url = globalThis.location.origin + "/" + details.url;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return details;
|
|
185
|
+
},
|
|
186
|
+
/**
|
|
187
|
+
* 处理fetch的配置
|
|
188
|
+
* @param {HttpxDetails} details
|
|
189
|
+
*/
|
|
190
|
+
handleFetchDetail(details) {
|
|
191
|
+
/**
|
|
192
|
+
* fetch的请求配置
|
|
193
|
+
* @type {RequestInit}
|
|
194
|
+
**/
|
|
195
|
+
let fetchRequestInit = {};
|
|
196
|
+
if (
|
|
197
|
+
(details.method === "GET" || details.method === "HEAD") &&
|
|
198
|
+
details.data != null
|
|
199
|
+
) {
|
|
200
|
+
/* GET 或 HEAD 方法的请求不能包含 body 信息 */
|
|
201
|
+
Reflect.deleteProperty(details, "data");
|
|
202
|
+
}
|
|
203
|
+
/* 中止信号控制器 */
|
|
204
|
+
let abortController = new AbortController();
|
|
205
|
+
let signal = abortController.signal;
|
|
206
|
+
signal.onabort = () => {
|
|
207
|
+
details.onabort({
|
|
208
|
+
isFetch: true,
|
|
209
|
+
responseText: "",
|
|
210
|
+
response: null,
|
|
211
|
+
readyState: 4,
|
|
212
|
+
responseHeaders: "",
|
|
213
|
+
status: 0,
|
|
214
|
+
statusText: "",
|
|
215
|
+
error: "aborted",
|
|
216
|
+
});
|
|
217
|
+
};
|
|
218
|
+
fetchRequestInit.method = details.method ?? "GET";
|
|
219
|
+
fetchRequestInit.headers = details.headers;
|
|
220
|
+
fetchRequestInit.body = details.data;
|
|
221
|
+
fetchRequestInit.mode = "cors";
|
|
222
|
+
fetchRequestInit.credentials = "include";
|
|
223
|
+
fetchRequestInit.cache = "no-cache";
|
|
224
|
+
fetchRequestInit.redirect = "follow";
|
|
225
|
+
fetchRequestInit.referrerPolicy = "origin-when-cross-origin";
|
|
226
|
+
fetchRequestInit.signal = signal;
|
|
227
|
+
Object.assign(fetchRequestInit, details.fetchInit || {});
|
|
228
|
+
return {
|
|
229
|
+
fetchDetails: details,
|
|
230
|
+
fetchRequestInit: fetchRequestInit,
|
|
231
|
+
abortController: abortController,
|
|
232
|
+
};
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
const HttpxCallBack = {
|
|
236
|
+
/**
|
|
237
|
+
* onabort请求被取消-触发
|
|
238
|
+
* @param {HttpxDetails} details 配置
|
|
239
|
+
* @param {()=>void} resolve 回调
|
|
240
|
+
* @param {any[]} argumentsList 参数列表
|
|
241
|
+
*/
|
|
242
|
+
onAbort(details, resolve, argumentsList) {
|
|
243
|
+
if ("onabort" in details) {
|
|
244
|
+
details.onabort.apply(this, argumentsList);
|
|
245
|
+
} else if ("onabort" in defaultDetails) {
|
|
246
|
+
defaultDetails.onabort.apply(this, argumentsList);
|
|
247
|
+
}
|
|
248
|
+
resolve({
|
|
249
|
+
status: false,
|
|
250
|
+
data: [...argumentsList],
|
|
251
|
+
msg: "请求被取消",
|
|
252
|
+
type: "onabort",
|
|
253
|
+
});
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* onerror请求异常-触发
|
|
258
|
+
* @param {HttpxDetails} details 配置
|
|
259
|
+
* @param {()=>void} resolve 回调
|
|
260
|
+
* @param {any[]} argumentsList 响应的参数列表
|
|
261
|
+
*/
|
|
262
|
+
onError(details, resolve, argumentsList) {
|
|
263
|
+
if ("onerror" in details) {
|
|
264
|
+
details.onerror.apply(this, argumentsList);
|
|
265
|
+
} else if ("onerror" in defaultDetails) {
|
|
266
|
+
defaultDetails.onerror.apply(this, argumentsList);
|
|
267
|
+
}
|
|
268
|
+
let response = argumentsList;
|
|
269
|
+
if (response.length) {
|
|
270
|
+
response = response[0];
|
|
271
|
+
}
|
|
272
|
+
resolve({
|
|
273
|
+
status: false,
|
|
274
|
+
data: response,
|
|
275
|
+
details: details,
|
|
276
|
+
msg: "请求异常",
|
|
277
|
+
type: "onerror",
|
|
278
|
+
});
|
|
279
|
+
},
|
|
280
|
+
/**
|
|
281
|
+
* ontimeout请求超时-触发
|
|
282
|
+
* @param {HttpxDetails} details 配置
|
|
283
|
+
* @param {()=>void} resolve 回调
|
|
284
|
+
* @param {any[]} argumentsList 参数列表
|
|
285
|
+
*/
|
|
286
|
+
onTimeout(details, resolve, argumentsList) {
|
|
287
|
+
if ("ontimeout" in details) {
|
|
288
|
+
details.ontimeout.apply(this, argumentsList);
|
|
289
|
+
} else if ("ontimeout" in defaultDetails) {
|
|
290
|
+
defaultDetails.ontimeout.apply(this, argumentsList);
|
|
291
|
+
}
|
|
292
|
+
resolve({
|
|
293
|
+
status: false,
|
|
294
|
+
data: [...argumentsList],
|
|
295
|
+
msg: "请求超时",
|
|
296
|
+
type: "ontimeout",
|
|
297
|
+
});
|
|
298
|
+
},
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* onloadstart请求开始-触发
|
|
302
|
+
* @param {HttpxDetails} details 配置
|
|
303
|
+
* @param {any[]} argumentsList 参数列表
|
|
304
|
+
*/
|
|
305
|
+
onLoadStart(details, argumentsList) {
|
|
306
|
+
if ("onloadstart" in details) {
|
|
307
|
+
details.onloadstart.apply(this, argumentsList);
|
|
308
|
+
} else if ("onloadstart" in defaultDetails) {
|
|
309
|
+
defaultDetails.onloadstart.apply(this, argumentsList);
|
|
310
|
+
}
|
|
311
|
+
},
|
|
312
|
+
/**
|
|
313
|
+
* onload加载完毕-触发
|
|
314
|
+
* @param {HttpxDetails} details 请求的配置
|
|
315
|
+
* @param {()=>void} resolve 回调
|
|
316
|
+
* @param {...HttpxAsyncResultData[]} argumentsList 参数列表
|
|
317
|
+
*/
|
|
318
|
+
onLoad(details, resolve, argumentsList) {
|
|
319
|
+
/* X浏览器会因为设置了responseType导致不返回responseText */
|
|
320
|
+
let Response = argumentsList[0];
|
|
321
|
+
/* responseText为空,response不为空的情况 */
|
|
322
|
+
if (
|
|
323
|
+
Utils.isNull(Response["responseText"]) &&
|
|
324
|
+
Utils.isNotNull(Response["response"])
|
|
325
|
+
) {
|
|
326
|
+
if (typeof Response["response"] === "object") {
|
|
327
|
+
Utils.tryCatch().run(() => {
|
|
328
|
+
Response["responseText"] = JSON.stringify(Response["response"]);
|
|
329
|
+
});
|
|
330
|
+
} else {
|
|
331
|
+
Response["responseText"] = Response["response"];
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/* response为空,responseText不为空的情况 */
|
|
336
|
+
if (
|
|
337
|
+
Response["response"] == null &&
|
|
338
|
+
typeof Response["responseText"] === "string" &&
|
|
339
|
+
Response["responseText"].trim() !== ""
|
|
340
|
+
) {
|
|
341
|
+
let newResponse = Response["responseText"];
|
|
342
|
+
if (details.responseType === "json") {
|
|
343
|
+
newResponse = Utils.toJSON(Response["responseText"]);
|
|
344
|
+
} else if (details.responseType === "document") {
|
|
345
|
+
let parser = new DOMParser();
|
|
346
|
+
newResponse = parser.parseFromString(
|
|
347
|
+
Response["responseText"],
|
|
348
|
+
"text/html"
|
|
349
|
+
);
|
|
350
|
+
} else if (details.responseType === "arraybuffer") {
|
|
351
|
+
let encoder = new TextEncoder();
|
|
352
|
+
let arrayBuffer = encoder.encode(Response["responseText"]);
|
|
353
|
+
newResponse = arrayBuffer;
|
|
354
|
+
} else if (details.responseType === "blob") {
|
|
355
|
+
let encoder = new TextEncoder();
|
|
356
|
+
let arrayBuffer = encoder.encode(Response["responseText"]);
|
|
357
|
+
newResponse = new Blob([arrayBuffer]);
|
|
358
|
+
} else {
|
|
359
|
+
newResponse = Response["responseText"];
|
|
360
|
+
}
|
|
361
|
+
try {
|
|
362
|
+
Response["response"] = newResponse;
|
|
363
|
+
} catch (error) {
|
|
364
|
+
console.warn("response 无法被覆盖");
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
/* Stay扩展中没有finalUrl,对应的是responseURL */
|
|
368
|
+
if (Response["finalUrl"] == null && Response["responseURL"] != null) {
|
|
369
|
+
Response["finalUrl"] = Response["responseURL"];
|
|
370
|
+
}
|
|
371
|
+
/* 状态码2xx都是成功的 */
|
|
372
|
+
if (Math.floor(Response.status / 100) === 2) {
|
|
373
|
+
resolve({
|
|
374
|
+
status: true,
|
|
375
|
+
data: Response,
|
|
376
|
+
details: details,
|
|
377
|
+
msg: "请求完毕",
|
|
378
|
+
type: "onload",
|
|
379
|
+
});
|
|
380
|
+
} else {
|
|
381
|
+
HttpxCallBack.onError(details, resolve, argumentsList);
|
|
382
|
+
}
|
|
383
|
+
},
|
|
384
|
+
/**
|
|
385
|
+
* onprogress上传进度-触发
|
|
386
|
+
* @param {HttpxDetails} details 配置
|
|
387
|
+
* @param {any[]} argumentsList 参数列表
|
|
388
|
+
*/
|
|
389
|
+
onProgress(details, argumentsList) {
|
|
390
|
+
if ("onprogress" in details) {
|
|
391
|
+
details.onprogress.apply(this, argumentsList);
|
|
392
|
+
} else if ("onprogress" in defaultDetails) {
|
|
393
|
+
defaultDetails.onprogress.apply(this, argumentsList);
|
|
394
|
+
}
|
|
395
|
+
},
|
|
396
|
+
/**
|
|
397
|
+
* onreadystatechange准备状态改变-触发
|
|
398
|
+
* @param {HttpxDetails} details 配置
|
|
399
|
+
* @param {any[]} argumentsList 参数列表
|
|
400
|
+
*/
|
|
401
|
+
onReadyStateChange(details, argumentsList) {
|
|
402
|
+
if ("onreadystatechange" in details) {
|
|
403
|
+
details.onreadystatechange.apply(this, argumentsList);
|
|
404
|
+
} else if ("onreadystatechange" in defaultDetails) {
|
|
405
|
+
defaultDetails.onreadystatechange.apply(this, argumentsList);
|
|
406
|
+
}
|
|
407
|
+
},
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
const HttpxRequest = {
|
|
411
|
+
/**
|
|
412
|
+
* 发送请求
|
|
413
|
+
* @param {HttpxDetails} details
|
|
414
|
+
*/
|
|
415
|
+
request(details) {
|
|
416
|
+
if (LOG_DETAILS) {
|
|
417
|
+
console.log("Httpx请求配置👇", details);
|
|
418
|
+
}
|
|
419
|
+
if (typeof HttpxRequestHook.beforeRequestCallBack === "function") {
|
|
420
|
+
let hookResult = HttpxRequestHook.beforeRequestCallBack(details);
|
|
421
|
+
if (typeof hookResult === "boolean" && !hookResult) {
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
if (details.fetch) {
|
|
426
|
+
const { fetchDetails, fetchRequestInit, abortController } =
|
|
427
|
+
HttpxRequestDetails.handleFetchDetail(details);
|
|
428
|
+
this.fetch(fetchDetails, fetchRequestInit, abortController);
|
|
429
|
+
} else {
|
|
430
|
+
Reflect.deleteProperty(details, "fetchInit");
|
|
431
|
+
this.xmlHttpRequest(details);
|
|
432
|
+
}
|
|
433
|
+
},
|
|
434
|
+
/**
|
|
435
|
+
* 使用油猴函数GM_xmlhttpRequest发送请求
|
|
436
|
+
* @param {HttpxDetails} details
|
|
437
|
+
*/
|
|
438
|
+
xmlHttpRequest(details) {
|
|
439
|
+
GM_Api.xmlHttpRequest(details);
|
|
440
|
+
},
|
|
441
|
+
/**
|
|
442
|
+
* 使用fetch发送请求
|
|
443
|
+
* @param {HttpxDetails} details
|
|
444
|
+
* @param {RequestInit} fetchRequestInit
|
|
445
|
+
* @param {AbortController} abortController
|
|
446
|
+
*/
|
|
447
|
+
fetch(details, fetchRequestInit, abortController) {
|
|
448
|
+
fetch(details.url, fetchRequestInit)
|
|
449
|
+
.then(async (resp) => {
|
|
450
|
+
/**
|
|
451
|
+
* @type {HttpxAsyncResultData}
|
|
452
|
+
*/
|
|
453
|
+
let httpxResponse = {
|
|
454
|
+
isFetch: true,
|
|
455
|
+
finalUrl: resp.url,
|
|
456
|
+
readyState: 4,
|
|
457
|
+
status: resp.status,
|
|
458
|
+
statusText: resp.statusText,
|
|
459
|
+
response: void 0,
|
|
460
|
+
responseFetchHeaders: resp.headers,
|
|
461
|
+
responseHeaders: "",
|
|
462
|
+
responseText: void 0,
|
|
463
|
+
responseType: details.responseType,
|
|
464
|
+
responseXML: void 0,
|
|
465
|
+
};
|
|
466
|
+
Object.assign(httpxResponse, details.context || {});
|
|
467
|
+
|
|
468
|
+
for (const [key, value] of resp.headers.entries()) {
|
|
469
|
+
httpxResponse.responseHeaders += `${key}: ${value}\n`;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/* 如果是流式传输,直接返回 */
|
|
473
|
+
if (
|
|
474
|
+
details.responseType === "stream" ||
|
|
475
|
+
(resp.headers.has("Content-Type") &&
|
|
476
|
+
resp.headers.get("Content-Type").includes("text/event-stream"))
|
|
477
|
+
) {
|
|
478
|
+
httpxResponse["isStream"] = true;
|
|
479
|
+
httpxResponse.response = resp.body;
|
|
480
|
+
Reflect.deleteProperty(httpxResponse, "responseText");
|
|
481
|
+
Reflect.deleteProperty(httpxResponse, "responseXML");
|
|
482
|
+
details.onload(httpxResponse);
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/** 响应 */
|
|
487
|
+
let response = "";
|
|
488
|
+
/** 响应字符串 */
|
|
489
|
+
let responseText = "";
|
|
490
|
+
/** 响应xml文档 */
|
|
491
|
+
let responseXML = "";
|
|
492
|
+
|
|
493
|
+
let arrayBuffer = await resp.arrayBuffer;
|
|
494
|
+
|
|
495
|
+
let encoding = "utf-8";
|
|
496
|
+
if (resp.headers.has("Content-Type")) {
|
|
497
|
+
let charsetMatched = resp.headers
|
|
498
|
+
.get("Content-Type")
|
|
499
|
+
.match(/charset=(.+)/);
|
|
500
|
+
if (charsetMatched) {
|
|
501
|
+
encoding = charsetMatched[1];
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
let textDecoder = new TextDecoder(encoding);
|
|
505
|
+
responseText = textDecoder.decode(await resp.arrayBuffer());
|
|
506
|
+
response = responseText;
|
|
507
|
+
|
|
508
|
+
if (details.responseType === "arraybuffer") {
|
|
509
|
+
response = arrayBuffer;
|
|
510
|
+
} else if (details.responseType === "blob") {
|
|
511
|
+
response = new Blob([arrayBuffer]);
|
|
512
|
+
} else if (
|
|
513
|
+
details.responseType === "document" ||
|
|
514
|
+
details.responseType == null
|
|
515
|
+
) {
|
|
516
|
+
let parser = new DOMParser();
|
|
517
|
+
response = parser.parseFromString(responseText, "text/html");
|
|
518
|
+
} else if (details.responseType === "json") {
|
|
519
|
+
response = Utils.toJSON(responseText);
|
|
520
|
+
}
|
|
521
|
+
let parser = new DOMParser();
|
|
522
|
+
responseXML = parser.parseFromString(responseText, "text/xml");
|
|
523
|
+
|
|
524
|
+
httpxResponse.response = response;
|
|
525
|
+
httpxResponse.responseText = responseText;
|
|
526
|
+
httpxResponse.responseXML = responseXML;
|
|
527
|
+
|
|
528
|
+
details.onload(httpxResponse);
|
|
529
|
+
})
|
|
530
|
+
.catch((err) => {
|
|
531
|
+
if (err.name === "AbortError") {
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
details.onerror({
|
|
535
|
+
isFetch: true,
|
|
536
|
+
finalUrl: details.url,
|
|
537
|
+
readyState: 4,
|
|
538
|
+
status: 0,
|
|
539
|
+
statusText: "",
|
|
540
|
+
responseHeaders: "",
|
|
541
|
+
responseText: "",
|
|
542
|
+
error: err,
|
|
543
|
+
});
|
|
544
|
+
});
|
|
545
|
+
details.onloadstart({
|
|
546
|
+
isFetch: true,
|
|
547
|
+
finalUrl: details.url,
|
|
548
|
+
readyState: 1,
|
|
549
|
+
responseHeaders: "",
|
|
550
|
+
responseText: "",
|
|
551
|
+
status: 0,
|
|
552
|
+
statusText: "",
|
|
553
|
+
});
|
|
554
|
+
return {
|
|
555
|
+
abort() {
|
|
556
|
+
abortController.abort();
|
|
557
|
+
},
|
|
558
|
+
};
|
|
559
|
+
},
|
|
560
|
+
};
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* 覆盖当前配置
|
|
564
|
+
* @param {HttpxDetailsConfig} details
|
|
565
|
+
*/
|
|
566
|
+
this.config = function (details = {}) {
|
|
567
|
+
if ("logDetails" in details && typeof details["logDetails"] === "boolean") {
|
|
568
|
+
LOG_DETAILS = details["logDetails"];
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
defaultDetails = Utils.assign(defaultDetails, details);
|
|
572
|
+
};
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* 修改xmlHttpRequest
|
|
576
|
+
* @param {Function} httpRequest 网络请求函数
|
|
577
|
+
*/
|
|
578
|
+
this.setXMLHttpRequest = function (httpRequest) {
|
|
579
|
+
GM_Api.xmlHttpRequest = httpRequest;
|
|
580
|
+
};
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* GET 请求
|
|
584
|
+
* @param {...HttpxDetails|string} args
|
|
585
|
+
* @returns {Promise< HttpxAsyncResult >}
|
|
586
|
+
*/
|
|
587
|
+
this.get = async function (...args) {
|
|
588
|
+
let details = {};
|
|
589
|
+
if (typeof args[0] === "string") {
|
|
590
|
+
details.url = args[0];
|
|
591
|
+
if (typeof args[1] === "object") {
|
|
592
|
+
details = args[1];
|
|
593
|
+
details.url = args[0];
|
|
594
|
+
}
|
|
595
|
+
} else {
|
|
596
|
+
details = args[0];
|
|
597
|
+
}
|
|
598
|
+
return new Promise((resolve) => {
|
|
599
|
+
let requestDetails = HttpxRequestDetails.getDetails(
|
|
600
|
+
"get",
|
|
601
|
+
resolve,
|
|
602
|
+
details
|
|
603
|
+
);
|
|
604
|
+
Reflect.deleteProperty(requestDetails, "onprogress");
|
|
605
|
+
requestDetails = HttpxRequestDetails.handle(requestDetails);
|
|
606
|
+
HttpxRequest.request(requestDetails);
|
|
607
|
+
});
|
|
608
|
+
};
|
|
609
|
+
/**
|
|
610
|
+
* POST 请求
|
|
611
|
+
* @param {...HttpxDetails|string} args
|
|
612
|
+
* @returns {Promise< HttpxAsyncResult >}
|
|
613
|
+
*/
|
|
614
|
+
this.post = async function (...args) {
|
|
615
|
+
let details = {};
|
|
616
|
+
if (typeof args[0] === "string") {
|
|
617
|
+
details.url = args[0];
|
|
618
|
+
if (typeof args[1] === "object") {
|
|
619
|
+
details = args[1];
|
|
620
|
+
details.url = args[0];
|
|
621
|
+
}
|
|
622
|
+
} else {
|
|
623
|
+
details = args[0];
|
|
624
|
+
}
|
|
625
|
+
return new Promise((resolve) => {
|
|
626
|
+
let requestDetails = HttpxRequestDetails.getDetails(
|
|
627
|
+
"post",
|
|
628
|
+
resolve,
|
|
629
|
+
details
|
|
630
|
+
);
|
|
631
|
+
requestDetails = HttpxRequestDetails.handle(requestDetails);
|
|
632
|
+
HttpxRequest.request(requestDetails);
|
|
633
|
+
});
|
|
634
|
+
};
|
|
635
|
+
/**
|
|
636
|
+
* HEAD 请求
|
|
637
|
+
* @param {...HttpxDetails|string} args
|
|
638
|
+
* @returns {Promise< HttpxAsyncResult >}
|
|
639
|
+
*/
|
|
640
|
+
this.head = async function (...args) {
|
|
641
|
+
let details = {};
|
|
642
|
+
if (typeof args[0] === "string") {
|
|
643
|
+
details.url = args[0];
|
|
644
|
+
if (typeof args[1] === "object") {
|
|
645
|
+
details = args[1];
|
|
646
|
+
details.url = args[0];
|
|
647
|
+
}
|
|
648
|
+
} else {
|
|
649
|
+
details = args[0];
|
|
650
|
+
}
|
|
651
|
+
return new Promise((resolve) => {
|
|
652
|
+
let requestDetails = HttpxRequestDetails.getDetails(
|
|
653
|
+
"head",
|
|
654
|
+
resolve,
|
|
655
|
+
details
|
|
656
|
+
);
|
|
657
|
+
Reflect.deleteProperty(requestDetails, "onprogress");
|
|
658
|
+
requestDetails = HttpxRequestDetails.handle(requestDetails);
|
|
659
|
+
HttpxRequest.request(requestDetails);
|
|
660
|
+
});
|
|
661
|
+
};
|
|
662
|
+
|
|
663
|
+
/**
|
|
664
|
+
* OPTIONS 请求
|
|
665
|
+
* @param {...HttpxDetails|string} args
|
|
666
|
+
* @returns {Promise< HttpxAsyncResult >}
|
|
667
|
+
*/
|
|
668
|
+
this.options = async function (...args) {
|
|
669
|
+
let details = {};
|
|
670
|
+
if (typeof args[0] === "string") {
|
|
671
|
+
details.url = args[0];
|
|
672
|
+
if (typeof args[1] === "object") {
|
|
673
|
+
details = args[1];
|
|
674
|
+
details.url = args[0];
|
|
675
|
+
}
|
|
676
|
+
} else {
|
|
677
|
+
details = args[0];
|
|
678
|
+
}
|
|
679
|
+
return new Promise((resolve) => {
|
|
680
|
+
let requestDetails = HttpxRequestDetails.getDetails(
|
|
681
|
+
"options",
|
|
682
|
+
resolve,
|
|
683
|
+
details
|
|
684
|
+
);
|
|
685
|
+
Reflect.deleteProperty(requestDetails, "onprogress");
|
|
686
|
+
requestDetails = HttpxRequestDetails.handle(requestDetails);
|
|
687
|
+
HttpxRequest.request(requestDetails);
|
|
688
|
+
});
|
|
689
|
+
};
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* DELETE 请求
|
|
693
|
+
* @param {...HttpxDetails|string} args
|
|
694
|
+
* @returns {Promise< HttpxAsyncResult >}
|
|
695
|
+
*/
|
|
696
|
+
this.delete = async function (...args) {
|
|
697
|
+
let details = {};
|
|
698
|
+
if (typeof args[0] === "string") {
|
|
699
|
+
details.url = args[0];
|
|
700
|
+
if (typeof args[1] === "object") {
|
|
701
|
+
details = args[1];
|
|
702
|
+
details.url = args[0];
|
|
703
|
+
}
|
|
704
|
+
} else {
|
|
705
|
+
details = args[0];
|
|
706
|
+
}
|
|
707
|
+
return new Promise((resolve) => {
|
|
708
|
+
let requestDetails = HttpxRequestDetails.getDetails(
|
|
709
|
+
"delete",
|
|
710
|
+
resolve,
|
|
711
|
+
details
|
|
712
|
+
);
|
|
713
|
+
Reflect.deleteProperty(requestDetails, "onprogress");
|
|
714
|
+
requestDetails = HttpxRequestDetails.handle(requestDetails);
|
|
715
|
+
HttpxRequest.request(requestDetails);
|
|
716
|
+
});
|
|
717
|
+
};
|
|
718
|
+
|
|
719
|
+
/**
|
|
720
|
+
* PUT 请求
|
|
721
|
+
* @param {...HttpxDetails|string} args
|
|
722
|
+
* @returns {Promise< HttpxAsyncResult >}
|
|
723
|
+
*/
|
|
724
|
+
this.put = async function (...args) {
|
|
725
|
+
let details = {};
|
|
726
|
+
if (typeof args[0] === "string") {
|
|
727
|
+
details.url = args[0];
|
|
728
|
+
if (typeof args[1] === "object") {
|
|
729
|
+
details = args[1];
|
|
730
|
+
details.url = args[0];
|
|
731
|
+
}
|
|
732
|
+
} else {
|
|
733
|
+
details = args[0];
|
|
734
|
+
}
|
|
735
|
+
return new Promise((resolve) => {
|
|
736
|
+
let requestDetails = HttpxRequestDetails.getDetails(
|
|
737
|
+
"put",
|
|
738
|
+
resolve,
|
|
739
|
+
details
|
|
740
|
+
);
|
|
741
|
+
requestDetails = HttpxRequestDetails.handle(requestDetails);
|
|
742
|
+
HttpxRequest.request(requestDetails);
|
|
743
|
+
});
|
|
744
|
+
};
|
|
745
|
+
};
|
|
746
|
+
|
|
747
|
+
export { Httpx };
|