@fangzhongya/utils 0.0.38 → 0.0.39

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.
Files changed (35) hide show
  1. package/dist/basic/index.cjs +1 -1
  2. package/dist/basic/index.js +1 -1
  3. package/dist/{chunk-SZ3EQ45X.js → chunk-CFR7GIIL.js} +8 -4
  4. package/dist/{chunk-TTIQUN2J.cjs → chunk-PGENJCCV.cjs} +12 -8
  5. package/dist/chunk-PW76Z25D.cjs +249 -0
  6. package/dist/{chunk-OZWQIUPS.cjs → chunk-UHKL2RG3.cjs} +5 -5
  7. package/dist/{chunk-L5HSTRIG.js → chunk-YKNGDK4I.js} +4 -4
  8. package/dist/chunk-ZLEU2YQ2.js +249 -0
  9. package/dist/{index-DQTqufH0.d.ts → index-9-f0oXM3.d.ts} +4 -2
  10. package/dist/{index-CTT_peAX.d.cts → index-_GH04n6g.d.cts} +4 -2
  11. package/dist/index.cjs +28 -28
  12. package/dist/index.d.cts +1 -1
  13. package/dist/index.d.ts +1 -1
  14. package/dist/index.js +31 -31
  15. package/dist/judge/index.cjs +6 -6
  16. package/dist/judge/index.js +5 -5
  17. package/dist/judge/matchs.cjs +3 -3
  18. package/dist/judge/matchs.js +2 -2
  19. package/dist/load/index.cjs +3 -3
  20. package/dist/load/index.js +4 -4
  21. package/dist/window/download.cjs +6 -2
  22. package/dist/window/download.d.cts +41 -19
  23. package/dist/window/download.d.ts +41 -19
  24. package/dist/window/download.js +5 -1
  25. package/dist/window/index.cjs +8 -4
  26. package/dist/window/index.d.cts +1 -1
  27. package/dist/window/index.d.ts +1 -1
  28. package/dist/window/index.js +9 -5
  29. package/package.json +1 -1
  30. package/dist/chunk-LHMAKOVB.cjs +0 -123
  31. package/dist/chunk-UQM7IS4W.js +0 -123
  32. package/dist/{chunk-IAKHOOY7.js → chunk-F4P3HMNK.js} +3 -3
  33. package/dist/{chunk-NGQKVTCR.cjs → chunk-T22I7TJQ.cjs} +3 -3
  34. package/dist/{chunk-FRGDQOX4.js → chunk-T2QKEABG.js} +3 -3
  35. package/dist/{chunk-BD6DK4QK.cjs → chunk-XXS5G6S6.cjs} +2 -2
@@ -34,10 +34,10 @@ require('../chunk-GD3OA7GU.cjs');
34
34
  require('../chunk-MHHMXDHD.cjs');
35
35
  require('../chunk-OJBZ7UUC.cjs');
36
36
  require('../chunk-JR6ZN6QD.cjs');
37
- require('../chunk-XW3XIK3D.cjs');
38
37
  require('../chunk-2H3KVSFA.cjs');
39
38
  require('../chunk-ILJLXJ5O.cjs');
40
39
  require('../chunk-PW7RP73J.cjs');
40
+ require('../chunk-XW3XIK3D.cjs');
41
41
  require('../chunk-UEVMS6QD.cjs');
42
42
  require('../chunk-OQL4GIEJ.cjs');
43
43
  require('../chunk-A5LHXE5X.cjs');
@@ -34,10 +34,10 @@ import "../chunk-ZVBCHJA5.js";
34
34
  import "../chunk-K33LOE73.js";
35
35
  import "../chunk-LPMR5W6M.js";
36
36
  import "../chunk-DMZP4RPN.js";
37
- import "../chunk-O34QAOO7.js";
38
37
  import "../chunk-USIMBBLW.js";
39
38
  import "../chunk-P7AWHISY.js";
40
39
  import "../chunk-A276ZDLP.js";
40
+ import "../chunk-O34QAOO7.js";
41
41
  import "../chunk-4OBNLDTJ.js";
42
42
  import "../chunk-EWJJKQIO.js";
43
43
  import "../chunk-GYE23WAN.js";
@@ -1,20 +1,22 @@
1
- import {
2
- copy
3
- } from "./chunk-W45DTA4D.js";
4
1
  import {
5
2
  downloadCSV,
6
3
  downloadFile,
7
4
  downloadFromURL,
5
+ downloadImage,
8
6
  downloadJSON,
7
+ downloadMultipleFiles,
9
8
  downloadText,
10
9
  downloadViaAJAX
11
- } from "./chunk-UQM7IS4W.js";
10
+ } from "./chunk-ZLEU2YQ2.js";
12
11
  import {
13
12
  getAllParams,
14
13
  getParam,
15
14
  getUrlParam,
16
15
  getUrlParams
17
16
  } from "./chunk-MCT2IB67.js";
17
+ import {
18
+ copy
19
+ } from "./chunk-W45DTA4D.js";
18
20
  import {
19
21
  __export
20
22
  } from "./chunk-MLKGABMK.js";
@@ -26,7 +28,9 @@ __export(window_exports, {
26
28
  downloadCSV: () => downloadCSV,
27
29
  downloadFile: () => downloadFile,
28
30
  downloadFromURL: () => downloadFromURL,
31
+ downloadImage: () => downloadImage,
29
32
  downloadJSON: () => downloadJSON,
33
+ downloadMultipleFiles: () => downloadMultipleFiles,
30
34
  downloadText: () => downloadText,
31
35
  downloadViaAJAX: () => downloadViaAJAX,
32
36
  getAllParams: () => getAllParams,
@@ -1,6 +1,5 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunkVYOTXPMMcjs = require('./chunk-VYOTXPMM.cjs');
4
3
 
5
4
 
6
5
 
@@ -8,7 +7,7 @@ var _chunkVYOTXPMMcjs = require('./chunk-VYOTXPMM.cjs');
8
7
 
9
8
 
10
9
 
11
- var _chunkLHMAKOVBcjs = require('./chunk-LHMAKOVB.cjs');
10
+ var _chunkPW76Z25Dcjs = require('./chunk-PW76Z25D.cjs');
12
11
 
13
12
 
14
13
 
@@ -17,18 +16,23 @@ var _chunkLHMAKOVBcjs = require('./chunk-LHMAKOVB.cjs');
17
16
  var _chunkZRO5GHYVcjs = require('./chunk-ZRO5GHYV.cjs');
18
17
 
19
18
 
19
+ var _chunkVYOTXPMMcjs = require('./chunk-VYOTXPMM.cjs');
20
+
21
+
20
22
  var _chunk75ZPJI57cjs = require('./chunk-75ZPJI57.cjs');
21
23
 
22
24
  // packages/window/index.ts
23
25
  var window_exports = {};
24
26
  _chunk75ZPJI57cjs.__export.call(void 0, window_exports, {
25
27
  copy: () => _chunkVYOTXPMMcjs.copy,
26
- downloadCSV: () => _chunkLHMAKOVBcjs.downloadCSV,
27
- downloadFile: () => _chunkLHMAKOVBcjs.downloadFile,
28
- downloadFromURL: () => _chunkLHMAKOVBcjs.downloadFromURL,
29
- downloadJSON: () => _chunkLHMAKOVBcjs.downloadJSON,
30
- downloadText: () => _chunkLHMAKOVBcjs.downloadText,
31
- downloadViaAJAX: () => _chunkLHMAKOVBcjs.downloadViaAJAX,
28
+ downloadCSV: () => _chunkPW76Z25Dcjs.downloadCSV,
29
+ downloadFile: () => _chunkPW76Z25Dcjs.downloadFile,
30
+ downloadFromURL: () => _chunkPW76Z25Dcjs.downloadFromURL,
31
+ downloadImage: () => _chunkPW76Z25Dcjs.downloadImage,
32
+ downloadJSON: () => _chunkPW76Z25Dcjs.downloadJSON,
33
+ downloadMultipleFiles: () => _chunkPW76Z25Dcjs.downloadMultipleFiles,
34
+ downloadText: () => _chunkPW76Z25Dcjs.downloadText,
35
+ downloadViaAJAX: () => _chunkPW76Z25Dcjs.downloadViaAJAX,
32
36
  getAllParams: () => _chunkZRO5GHYVcjs.getAllParams,
33
37
  getParam: () => _chunkZRO5GHYVcjs.getParam,
34
38
  getUrlParam: () => _chunkZRO5GHYVcjs.getUrlParam,
@@ -0,0 +1,249 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});// packages/window/download.ts
2
+ function downloadText(text, filename = "text.txt", mimeType = "text/plain") {
3
+ downloadFile(text, { filename, mimeType });
4
+ }
5
+ function downloadJSON(jsonData, filename = "data.json") {
6
+ downloadFile(jsonData, {
7
+ filename,
8
+ mimeType: "application/json"
9
+ });
10
+ }
11
+ function downloadCSV(data, filename = "data.csv", headers) {
12
+ let csvContent = "";
13
+ if (Array.isArray(data) && data.length > 0) {
14
+ if (Array.isArray(data[0])) {
15
+ const rows = data;
16
+ csvContent = rows.map(
17
+ (row) => row.map((cell) => `"${String(cell).replace(/"/g, '""')}"`).join(",")
18
+ ).join("\n");
19
+ } else if (typeof data[0] === "object") {
20
+ const objects = data;
21
+ const objectHeaders = headers || Object.keys(objects[0]);
22
+ csvContent = objectHeaders.map((header) => `"${String(header).replace(/"/g, '""')}"`).join(",") + "\n";
23
+ csvContent += objects.map(
24
+ (obj) => objectHeaders.map(
25
+ (header) => `"${String(obj[header] || "").replace(
26
+ /"/g,
27
+ '""'
28
+ )}"`
29
+ ).join(",")
30
+ ).join("\n");
31
+ }
32
+ }
33
+ downloadFile(csvContent, {
34
+ filename,
35
+ mimeType: "text/csv"
36
+ });
37
+ }
38
+ async function downloadViaAJAX(url, filename, options = {}) {
39
+ try {
40
+ const response = await fetch(url, {
41
+ method: "GET",
42
+ ...options
43
+ });
44
+ if (!response.ok) {
45
+ throw new Error(`HTTP error! status: ${response.status}`);
46
+ }
47
+ const blob = await response.blob();
48
+ let finalFilename = filename;
49
+ if (!finalFilename) {
50
+ const contentDisposition = response.headers.get(
51
+ "content-disposition"
52
+ );
53
+ if (contentDisposition) {
54
+ const filenameMatch = contentDisposition.match(/filename="?(.+?)"?$/);
55
+ if (filenameMatch) {
56
+ finalFilename = filenameMatch[1];
57
+ }
58
+ }
59
+ }
60
+ downloadFile(blob, { filename: finalFilename });
61
+ } catch (error) {
62
+ console.error("AJAX \u4E0B\u8F7D\u5931\u8D25:", error);
63
+ throw new Error(
64
+ `\u4E0B\u8F7D\u5931\u8D25: ${error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"}`
65
+ );
66
+ }
67
+ }
68
+ function downloadFile(data, options = {}) {
69
+ const {
70
+ filename = "download",
71
+ mimeType = "application/octet-stream",
72
+ charset = "utf-8",
73
+ bom = ""
74
+ } = options;
75
+ try {
76
+ let blobData;
77
+ if (data instanceof Blob) {
78
+ blobData = data;
79
+ } else if (typeof data === "object") {
80
+ const jsonString = JSON.stringify(data, null, 2);
81
+ blobData = bom + jsonString;
82
+ } else if (typeof data === "string") {
83
+ blobData = bom + data;
84
+ } else {
85
+ blobData = data;
86
+ }
87
+ const blob = new Blob([blobData], {
88
+ type: `${mimeType};charset=${charset}`
89
+ });
90
+ const blobUrl = URL.createObjectURL(blob);
91
+ const link = document.createElement("a");
92
+ link.href = blobUrl;
93
+ link.download = filename;
94
+ link.style.display = "none";
95
+ document.body.appendChild(link);
96
+ link.click();
97
+ setTimeout(() => {
98
+ document.body.removeChild(link);
99
+ URL.revokeObjectURL(blobUrl);
100
+ }, 100);
101
+ } catch (error) {
102
+ console.error("\u6587\u4EF6\u4E0B\u8F7D\u5931\u8D25:", error);
103
+ throw new Error(
104
+ `\u4E0B\u8F7D\u5931\u8D25: ${error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"}`
105
+ );
106
+ }
107
+ }
108
+ async function downloadFromURL(url, filename, options = {}) {
109
+ const {
110
+ useBlob = true,
111
+ // 默认使用 Blob 方式,确保能触发下载
112
+ headers = {},
113
+ timeout = 3e4
114
+ } = options;
115
+ try {
116
+ if (!useBlob) {
117
+ const link = document.createElement("a");
118
+ link.href = url;
119
+ link.download = filename || getFilenameFromURL(url);
120
+ link.style.display = "none";
121
+ link.target = "_blank";
122
+ document.body.appendChild(link);
123
+ link.click();
124
+ setTimeout(() => {
125
+ document.body.removeChild(link);
126
+ }, 100);
127
+ return;
128
+ }
129
+ const controller = new AbortController();
130
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
131
+ const response = await fetch(url, {
132
+ method: "GET",
133
+ headers,
134
+ signal: controller.signal
135
+ });
136
+ clearTimeout(timeoutId);
137
+ if (!response.ok) {
138
+ throw new Error(`HTTP error! status: ${response.status}`);
139
+ }
140
+ const blob = await response.blob();
141
+ let finalFilename = filename;
142
+ if (!finalFilename) {
143
+ const contentDisposition = response.headers.get(
144
+ "content-disposition"
145
+ );
146
+ if (contentDisposition) {
147
+ const filenameMatch = contentDisposition.match(
148
+ /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
149
+ );
150
+ if (filenameMatch && filenameMatch[1]) {
151
+ finalFilename = filenameMatch[1].replace(/['"]/g, "");
152
+ }
153
+ }
154
+ if (!finalFilename) {
155
+ finalFilename = getFilenameFromURL(url);
156
+ }
157
+ }
158
+ const mimeType = getMimeTypeFromBlob(blob, url);
159
+ downloadFile(blob, {
160
+ filename: finalFilename,
161
+ mimeType
162
+ });
163
+ } catch (error) {
164
+ console.error("URL \u4E0B\u8F7D\u5931\u8D25:", error);
165
+ if (error instanceof Error && error.name === "AbortError") {
166
+ throw new Error("\u4E0B\u8F7D\u8D85\u65F6\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\u6216\u6587\u4EF6\u5927\u5C0F");
167
+ }
168
+ if (useBlob) {
169
+ console.log("Blob \u65B9\u5F0F\u5931\u8D25\uFF0C\u5C1D\u8BD5\u76F4\u63A5\u4E0B\u8F7D...");
170
+ await downloadFromURL(url, filename, {
171
+ ...options,
172
+ useBlob: false
173
+ });
174
+ } else {
175
+ throw new Error(
176
+ `\u4E0B\u8F7D\u5931\u8D25: ${error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"}`
177
+ );
178
+ }
179
+ }
180
+ }
181
+ async function downloadImage(imageUrl, filename) {
182
+ await downloadFromURL(imageUrl, filename, {
183
+ useBlob: true,
184
+ headers: {
185
+ Accept: "image/*"
186
+ }
187
+ });
188
+ }
189
+ function getFilenameFromURL(url) {
190
+ try {
191
+ const urlObj = new URL(url);
192
+ const pathname = urlObj.pathname;
193
+ const filename = pathname.substring(pathname.lastIndexOf("/") + 1);
194
+ if (!filename || filename === "/" || !filename.includes(".")) {
195
+ const extension = getFileExtensionFromURL(url) || "bin";
196
+ return `download_${Date.now()}.${extension}`;
197
+ }
198
+ return decodeURIComponent(filename);
199
+ } catch (e) {
200
+ const extension = getFileExtensionFromURL(url) || "bin";
201
+ return `download_${Date.now()}.${extension}`;
202
+ }
203
+ }
204
+ function getFileExtensionFromURL(url) {
205
+ const match = url.match(/\.([a-zA-Z0-9]+)(?:[?#]|$)/);
206
+ return match ? match[1].toLowerCase() : null;
207
+ }
208
+ function getMimeTypeFromBlob(blob, url) {
209
+ if (blob.type && blob.type !== "application/octet-stream") {
210
+ return blob.type;
211
+ }
212
+ const extension = getFileExtensionFromURL(url);
213
+ const mimeTypes = {
214
+ jpg: "image/jpeg",
215
+ jpeg: "image/jpeg",
216
+ png: "image/png",
217
+ gif: "image/gif",
218
+ webp: "image/webp",
219
+ svg: "image/svg+xml",
220
+ pdf: "application/pdf",
221
+ txt: "text/plain",
222
+ json: "application/json",
223
+ csv: "text/csv",
224
+ xml: "application/xml",
225
+ zip: "application/zip",
226
+ mp3: "audio/mpeg",
227
+ mp4: "video/mp4",
228
+ avi: "video/x-msvideo"
229
+ };
230
+ return extension && mimeTypes[extension] ? mimeTypes[extension] : "application/octet-stream";
231
+ }
232
+ async function downloadMultipleFiles(downloads) {
233
+ return Promise.all(
234
+ downloads.map(
235
+ (download) => downloadFromURL(download.url, download.filename)
236
+ )
237
+ );
238
+ }
239
+
240
+
241
+
242
+
243
+
244
+
245
+
246
+
247
+
248
+
249
+ exports.downloadText = downloadText; exports.downloadJSON = downloadJSON; exports.downloadCSV = downloadCSV; exports.downloadViaAJAX = downloadViaAJAX; exports.downloadFile = downloadFile; exports.downloadFromURL = downloadFromURL; exports.downloadImage = downloadImage; exports.downloadMultipleFiles = downloadMultipleFiles;
@@ -27,16 +27,16 @@
27
27
  var _chunkV2DXOH6Bcjs = require('./chunk-V2DXOH6B.cjs');
28
28
 
29
29
 
30
- var _chunkNGQKVTCRcjs = require('./chunk-NGQKVTCR.cjs');
30
+ var _chunkT22I7TJQcjs = require('./chunk-T22I7TJQ.cjs');
31
31
 
32
32
 
33
- var _chunkZZEFL2TEcjs = require('./chunk-ZZEFL2TE.cjs');
33
+ var _chunkYGJOBIEOcjs = require('./chunk-YGJOBIEO.cjs');
34
34
 
35
35
 
36
- var _chunk2BY5RQHUcjs = require('./chunk-2BY5RQHU.cjs');
36
+ var _chunkZZEFL2TEcjs = require('./chunk-ZZEFL2TE.cjs');
37
37
 
38
38
 
39
- var _chunkYGJOBIEOcjs = require('./chunk-YGJOBIEO.cjs');
39
+ var _chunk2BY5RQHUcjs = require('./chunk-2BY5RQHU.cjs');
40
40
 
41
41
 
42
42
  var _chunk75ZPJI57cjs = require('./chunk-75ZPJI57.cjs');
@@ -69,7 +69,7 @@ _chunk75ZPJI57cjs.__export.call(void 0, judge_exports, {
69
69
  isTel: () => _chunkV2DXOH6Bcjs.isTel,
70
70
  isURL: () => _chunkV2DXOH6Bcjs.isURL,
71
71
  isWeChat: () => _chunkV2DXOH6Bcjs.isWeChat,
72
- matchs: () => _chunkNGQKVTCRcjs.matchs,
72
+ matchs: () => _chunkT22I7TJQcjs.matchs,
73
73
  matchsEnd: () => _chunkYGJOBIEOcjs.matchsEnd,
74
74
  matchsStart: () => _chunkZZEFL2TEcjs.matchsStart,
75
75
  matchsWhole: () => _chunk2BY5RQHUcjs.matchsWhole
@@ -27,16 +27,16 @@ import {
27
27
  } from "./chunk-PLNZCEDI.js";
28
28
  import {
29
29
  matchs
30
- } from "./chunk-FRGDQOX4.js";
30
+ } from "./chunk-T2QKEABG.js";
31
+ import {
32
+ matchsEnd
33
+ } from "./chunk-YNOFNHEK.js";
31
34
  import {
32
35
  matchsStart
33
36
  } from "./chunk-S6JRKYPY.js";
34
37
  import {
35
38
  matchsWhole
36
39
  } from "./chunk-IRGCP7KH.js";
37
- import {
38
- matchsEnd
39
- } from "./chunk-YNOFNHEK.js";
40
40
  import {
41
41
  __export
42
42
  } from "./chunk-MLKGABMK.js";
@@ -0,0 +1,249 @@
1
+ // packages/window/download.ts
2
+ function downloadText(text, filename = "text.txt", mimeType = "text/plain") {
3
+ downloadFile(text, { filename, mimeType });
4
+ }
5
+ function downloadJSON(jsonData, filename = "data.json") {
6
+ downloadFile(jsonData, {
7
+ filename,
8
+ mimeType: "application/json"
9
+ });
10
+ }
11
+ function downloadCSV(data, filename = "data.csv", headers) {
12
+ let csvContent = "";
13
+ if (Array.isArray(data) && data.length > 0) {
14
+ if (Array.isArray(data[0])) {
15
+ const rows = data;
16
+ csvContent = rows.map(
17
+ (row) => row.map((cell) => `"${String(cell).replace(/"/g, '""')}"`).join(",")
18
+ ).join("\n");
19
+ } else if (typeof data[0] === "object") {
20
+ const objects = data;
21
+ const objectHeaders = headers || Object.keys(objects[0]);
22
+ csvContent = objectHeaders.map((header) => `"${String(header).replace(/"/g, '""')}"`).join(",") + "\n";
23
+ csvContent += objects.map(
24
+ (obj) => objectHeaders.map(
25
+ (header) => `"${String(obj[header] || "").replace(
26
+ /"/g,
27
+ '""'
28
+ )}"`
29
+ ).join(",")
30
+ ).join("\n");
31
+ }
32
+ }
33
+ downloadFile(csvContent, {
34
+ filename,
35
+ mimeType: "text/csv"
36
+ });
37
+ }
38
+ async function downloadViaAJAX(url, filename, options = {}) {
39
+ try {
40
+ const response = await fetch(url, {
41
+ method: "GET",
42
+ ...options
43
+ });
44
+ if (!response.ok) {
45
+ throw new Error(`HTTP error! status: ${response.status}`);
46
+ }
47
+ const blob = await response.blob();
48
+ let finalFilename = filename;
49
+ if (!finalFilename) {
50
+ const contentDisposition = response.headers.get(
51
+ "content-disposition"
52
+ );
53
+ if (contentDisposition) {
54
+ const filenameMatch = contentDisposition.match(/filename="?(.+?)"?$/);
55
+ if (filenameMatch) {
56
+ finalFilename = filenameMatch[1];
57
+ }
58
+ }
59
+ }
60
+ downloadFile(blob, { filename: finalFilename });
61
+ } catch (error) {
62
+ console.error("AJAX \u4E0B\u8F7D\u5931\u8D25:", error);
63
+ throw new Error(
64
+ `\u4E0B\u8F7D\u5931\u8D25: ${error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"}`
65
+ );
66
+ }
67
+ }
68
+ function downloadFile(data, options = {}) {
69
+ const {
70
+ filename = "download",
71
+ mimeType = "application/octet-stream",
72
+ charset = "utf-8",
73
+ bom = ""
74
+ } = options;
75
+ try {
76
+ let blobData;
77
+ if (data instanceof Blob) {
78
+ blobData = data;
79
+ } else if (typeof data === "object") {
80
+ const jsonString = JSON.stringify(data, null, 2);
81
+ blobData = bom + jsonString;
82
+ } else if (typeof data === "string") {
83
+ blobData = bom + data;
84
+ } else {
85
+ blobData = data;
86
+ }
87
+ const blob = new Blob([blobData], {
88
+ type: `${mimeType};charset=${charset}`
89
+ });
90
+ const blobUrl = URL.createObjectURL(blob);
91
+ const link = document.createElement("a");
92
+ link.href = blobUrl;
93
+ link.download = filename;
94
+ link.style.display = "none";
95
+ document.body.appendChild(link);
96
+ link.click();
97
+ setTimeout(() => {
98
+ document.body.removeChild(link);
99
+ URL.revokeObjectURL(blobUrl);
100
+ }, 100);
101
+ } catch (error) {
102
+ console.error("\u6587\u4EF6\u4E0B\u8F7D\u5931\u8D25:", error);
103
+ throw new Error(
104
+ `\u4E0B\u8F7D\u5931\u8D25: ${error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"}`
105
+ );
106
+ }
107
+ }
108
+ async function downloadFromURL(url, filename, options = {}) {
109
+ const {
110
+ useBlob = true,
111
+ // 默认使用 Blob 方式,确保能触发下载
112
+ headers = {},
113
+ timeout = 3e4
114
+ } = options;
115
+ try {
116
+ if (!useBlob) {
117
+ const link = document.createElement("a");
118
+ link.href = url;
119
+ link.download = filename || getFilenameFromURL(url);
120
+ link.style.display = "none";
121
+ link.target = "_blank";
122
+ document.body.appendChild(link);
123
+ link.click();
124
+ setTimeout(() => {
125
+ document.body.removeChild(link);
126
+ }, 100);
127
+ return;
128
+ }
129
+ const controller = new AbortController();
130
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
131
+ const response = await fetch(url, {
132
+ method: "GET",
133
+ headers,
134
+ signal: controller.signal
135
+ });
136
+ clearTimeout(timeoutId);
137
+ if (!response.ok) {
138
+ throw new Error(`HTTP error! status: ${response.status}`);
139
+ }
140
+ const blob = await response.blob();
141
+ let finalFilename = filename;
142
+ if (!finalFilename) {
143
+ const contentDisposition = response.headers.get(
144
+ "content-disposition"
145
+ );
146
+ if (contentDisposition) {
147
+ const filenameMatch = contentDisposition.match(
148
+ /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
149
+ );
150
+ if (filenameMatch && filenameMatch[1]) {
151
+ finalFilename = filenameMatch[1].replace(/['"]/g, "");
152
+ }
153
+ }
154
+ if (!finalFilename) {
155
+ finalFilename = getFilenameFromURL(url);
156
+ }
157
+ }
158
+ const mimeType = getMimeTypeFromBlob(blob, url);
159
+ downloadFile(blob, {
160
+ filename: finalFilename,
161
+ mimeType
162
+ });
163
+ } catch (error) {
164
+ console.error("URL \u4E0B\u8F7D\u5931\u8D25:", error);
165
+ if (error instanceof Error && error.name === "AbortError") {
166
+ throw new Error("\u4E0B\u8F7D\u8D85\u65F6\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\u6216\u6587\u4EF6\u5927\u5C0F");
167
+ }
168
+ if (useBlob) {
169
+ console.log("Blob \u65B9\u5F0F\u5931\u8D25\uFF0C\u5C1D\u8BD5\u76F4\u63A5\u4E0B\u8F7D...");
170
+ await downloadFromURL(url, filename, {
171
+ ...options,
172
+ useBlob: false
173
+ });
174
+ } else {
175
+ throw new Error(
176
+ `\u4E0B\u8F7D\u5931\u8D25: ${error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"}`
177
+ );
178
+ }
179
+ }
180
+ }
181
+ async function downloadImage(imageUrl, filename) {
182
+ await downloadFromURL(imageUrl, filename, {
183
+ useBlob: true,
184
+ headers: {
185
+ Accept: "image/*"
186
+ }
187
+ });
188
+ }
189
+ function getFilenameFromURL(url) {
190
+ try {
191
+ const urlObj = new URL(url);
192
+ const pathname = urlObj.pathname;
193
+ const filename = pathname.substring(pathname.lastIndexOf("/") + 1);
194
+ if (!filename || filename === "/" || !filename.includes(".")) {
195
+ const extension = getFileExtensionFromURL(url) || "bin";
196
+ return `download_${Date.now()}.${extension}`;
197
+ }
198
+ return decodeURIComponent(filename);
199
+ } catch {
200
+ const extension = getFileExtensionFromURL(url) || "bin";
201
+ return `download_${Date.now()}.${extension}`;
202
+ }
203
+ }
204
+ function getFileExtensionFromURL(url) {
205
+ const match = url.match(/\.([a-zA-Z0-9]+)(?:[?#]|$)/);
206
+ return match ? match[1].toLowerCase() : null;
207
+ }
208
+ function getMimeTypeFromBlob(blob, url) {
209
+ if (blob.type && blob.type !== "application/octet-stream") {
210
+ return blob.type;
211
+ }
212
+ const extension = getFileExtensionFromURL(url);
213
+ const mimeTypes = {
214
+ jpg: "image/jpeg",
215
+ jpeg: "image/jpeg",
216
+ png: "image/png",
217
+ gif: "image/gif",
218
+ webp: "image/webp",
219
+ svg: "image/svg+xml",
220
+ pdf: "application/pdf",
221
+ txt: "text/plain",
222
+ json: "application/json",
223
+ csv: "text/csv",
224
+ xml: "application/xml",
225
+ zip: "application/zip",
226
+ mp3: "audio/mpeg",
227
+ mp4: "video/mp4",
228
+ avi: "video/x-msvideo"
229
+ };
230
+ return extension && mimeTypes[extension] ? mimeTypes[extension] : "application/octet-stream";
231
+ }
232
+ async function downloadMultipleFiles(downloads) {
233
+ return Promise.all(
234
+ downloads.map(
235
+ (download) => downloadFromURL(download.url, download.filename)
236
+ )
237
+ );
238
+ }
239
+
240
+ export {
241
+ downloadText,
242
+ downloadJSON,
243
+ downloadCSV,
244
+ downloadViaAJAX,
245
+ downloadFile,
246
+ downloadFromURL,
247
+ downloadImage,
248
+ downloadMultipleFiles
249
+ };
@@ -1,12 +1,14 @@
1
1
  import { copy } from './window/copy.js';
2
- import { downloadCSV, downloadFile, downloadFromURL, downloadJSON, downloadText, downloadViaAJAX } from './window/download.js';
2
+ import { downloadCSV, downloadFile, downloadFromURL, downloadImage, downloadJSON, downloadMultipleFiles, downloadText, downloadViaAJAX } from './window/download.js';
3
3
  import { getAllParams, getParam, getUrlParam, getUrlParams } from './window/getParam.js';
4
4
 
5
5
  declare const index_copy: typeof copy;
6
6
  declare const index_downloadCSV: typeof downloadCSV;
7
7
  declare const index_downloadFile: typeof downloadFile;
8
8
  declare const index_downloadFromURL: typeof downloadFromURL;
9
+ declare const index_downloadImage: typeof downloadImage;
9
10
  declare const index_downloadJSON: typeof downloadJSON;
11
+ declare const index_downloadMultipleFiles: typeof downloadMultipleFiles;
10
12
  declare const index_downloadText: typeof downloadText;
11
13
  declare const index_downloadViaAJAX: typeof downloadViaAJAX;
12
14
  declare const index_getAllParams: typeof getAllParams;
@@ -14,7 +16,7 @@ declare const index_getParam: typeof getParam;
14
16
  declare const index_getUrlParam: typeof getUrlParam;
15
17
  declare const index_getUrlParams: typeof getUrlParams;
16
18
  declare namespace index {
17
- export { index_copy as copy, index_downloadCSV as downloadCSV, index_downloadFile as downloadFile, index_downloadFromURL as downloadFromURL, index_downloadJSON as downloadJSON, index_downloadText as downloadText, index_downloadViaAJAX as downloadViaAJAX, index_getAllParams as getAllParams, index_getParam as getParam, index_getUrlParam as getUrlParam, index_getUrlParams as getUrlParams };
19
+ export { index_copy as copy, index_downloadCSV as downloadCSV, index_downloadFile as downloadFile, index_downloadFromURL as downloadFromURL, index_downloadImage as downloadImage, index_downloadJSON as downloadJSON, index_downloadMultipleFiles as downloadMultipleFiles, index_downloadText as downloadText, index_downloadViaAJAX as downloadViaAJAX, index_getAllParams as getAllParams, index_getParam as getParam, index_getUrlParam as getUrlParam, index_getUrlParams as getUrlParams };
18
20
  }
19
21
 
20
22
  export { index as i };