nhanh-pure-function 1.3.20 → 1.3.22
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/lib/Utility/Utility.js +95 -33
- package/package.json +1 -1
package/lib/Utility/Utility.js
CHANGED
|
@@ -226,28 +226,50 @@ export function _GetHrefName(href, defaultName = "file") {
|
|
|
226
226
|
* @param {string} href - 文件路径
|
|
227
227
|
* @param {string} [fileName] - 导出文件名
|
|
228
228
|
*/
|
|
229
|
-
export
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
229
|
+
export function _DownloadFile(href, fileName) {
|
|
230
|
+
return new Promise((resolve, reject) => {
|
|
231
|
+
_CheckConnectionWithXHR(href)
|
|
232
|
+
.then(() => {
|
|
233
|
+
try {
|
|
234
|
+
if (typeof fileName !== "string") {
|
|
235
|
+
fileName = _GetHrefName(href, "downloaded_file");
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
fetch(href)
|
|
239
|
+
.then((response) => {
|
|
240
|
+
if (!response.ok) {
|
|
241
|
+
throw new Error(`文件下载失败,状态码: ${response.status}`);
|
|
242
|
+
}
|
|
243
|
+
return response.blob();
|
|
244
|
+
})
|
|
245
|
+
.then((blob) => {
|
|
246
|
+
const url = URL.createObjectURL(blob); // 创建文件 URL
|
|
247
|
+
|
|
248
|
+
const a = document.createElement("a");
|
|
249
|
+
a.href = url;
|
|
250
|
+
a.download = decodeURIComponent(fileName);
|
|
251
|
+
|
|
252
|
+
// 临时将 a 标签添加到 DOM,然后触发点击事件,最后移除
|
|
253
|
+
document.body.appendChild(a);
|
|
254
|
+
a.click();
|
|
255
|
+
document.body.removeChild(a);
|
|
256
|
+
|
|
257
|
+
// 释放 URL 对象
|
|
258
|
+
URL.revokeObjectURL(url);
|
|
259
|
+
|
|
260
|
+
resolve();
|
|
261
|
+
})
|
|
262
|
+
.catch((error) => {
|
|
263
|
+
console.error("下载文件时发生错误:", error.message);
|
|
264
|
+
reject(error);
|
|
265
|
+
});
|
|
266
|
+
} catch (error) {
|
|
267
|
+
console.error("下载文件时发生错误:", error.message);
|
|
268
|
+
reject(error);
|
|
269
|
+
}
|
|
270
|
+
})
|
|
271
|
+
.catch(reject);
|
|
272
|
+
});
|
|
251
273
|
}
|
|
252
274
|
|
|
253
275
|
/**
|
|
@@ -384,13 +406,17 @@ export function _Debounce(fn, delay) {
|
|
|
384
406
|
* @returns {Function}
|
|
385
407
|
*/
|
|
386
408
|
export function _Throttle(fn, delay) {
|
|
387
|
-
let
|
|
409
|
+
let lastCallTime = -Infinity;
|
|
410
|
+
|
|
388
411
|
return function (...args) {
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
412
|
+
const now = performance.now();
|
|
413
|
+
if (now - lastCallTime > delay) {
|
|
414
|
+
lastCallTime = now;
|
|
415
|
+
try {
|
|
416
|
+
fn(...args);
|
|
417
|
+
} catch (error) {
|
|
418
|
+
console.error("Throttled function execution failed:", error);
|
|
419
|
+
}
|
|
394
420
|
}
|
|
395
421
|
};
|
|
396
422
|
}
|
|
@@ -556,16 +582,52 @@ export function _UpdateTargetByPath(model, path, value) {
|
|
|
556
582
|
*/
|
|
557
583
|
export function _CheckConnectionWithXHR(url) {
|
|
558
584
|
return new Promise((resolve, reject) => {
|
|
585
|
+
// 前置校验:确保 URL 合法
|
|
586
|
+
if (typeof url !== "string" || url.trim() === "" || !url.includes("://")) {
|
|
587
|
+
reject(new Error("Invalid URL: Must be a non-empty string"));
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
// 显式处理浏览器兼容性错误(如无效协议或非法字符)
|
|
592
|
+
try {
|
|
593
|
+
const xhr = new XMLHttpRequest();
|
|
594
|
+
xhr.open("HEAD", url, true);
|
|
595
|
+
} catch (error) {
|
|
596
|
+
reject(new Error(`Invalid URL format: ${error.message}`));
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
|
|
559
600
|
const xhr = new XMLHttpRequest();
|
|
560
|
-
xhr.open("HEAD", url, true);
|
|
601
|
+
xhr.open("HEAD", url, true);
|
|
602
|
+
|
|
603
|
+
// 统一错误处理逻辑
|
|
604
|
+
const handleError = (event) => {
|
|
605
|
+
reject(new Error(`Request failed: ${event.type}`));
|
|
606
|
+
};
|
|
607
|
+
|
|
561
608
|
xhr.onreadystatechange = function () {
|
|
562
609
|
if (xhr.readyState === XMLHttpRequest.DONE) {
|
|
563
|
-
|
|
564
|
-
|
|
610
|
+
// 兼容性处理:status=0 可能是跨域或网络错误
|
|
611
|
+
if (xhr.status === 0) {
|
|
612
|
+
reject(new Error("Network error or CORS blocked"));
|
|
613
|
+
} else if (xhr.status >= 200 && xhr.status < 300) {
|
|
614
|
+
resolve();
|
|
615
|
+
} else {
|
|
616
|
+
reject(new Error(`HTTP Error: ${xhr.status}`));
|
|
617
|
+
}
|
|
565
618
|
}
|
|
566
619
|
};
|
|
567
|
-
|
|
568
|
-
|
|
620
|
+
|
|
621
|
+
// 绑定所有可能的错误事件
|
|
622
|
+
xhr.onerror = handleError; // 网络层错误(如 DNS 解析失败)
|
|
623
|
+
xhr.onabort = handleError; // 请求被中止
|
|
624
|
+
xhr.ontimeout = handleError; // 超时
|
|
625
|
+
|
|
626
|
+
try {
|
|
627
|
+
xhr.send();
|
|
628
|
+
} catch (error) {
|
|
629
|
+
reject(new Error(`Request send failed: ${error.message}`));
|
|
630
|
+
}
|
|
569
631
|
});
|
|
570
632
|
}
|
|
571
633
|
|