ow
This commit is contained in:
1 parent
e740ec77ec
commit
ceb3e7beec
20 files changed
+2280
-138
No files matched your search
@@ -466,11 +466,16 @@ function timestamp(): string {
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载并打开文件(默认按 Excel 处理)
|
||||
* 关键防御:先探测 content-type——后端报错时返回的是 JSON 而不是文件
|
||||
* 裸 arraybuffer 请求(旁路通道):文件下载/分片取回/预览字节等面向字节的场景共用。
|
||||
* 关键防御与 downloadFile 同源——后端报错时回的是 JSON 而不是文件,
|
||||
* 按 content-type 探测后转成错误文案抛出(业务异常不再当字节流落盘)
|
||||
*/
|
||||
export async function downloadFile(options: DownloadOptions): Promise<void> {
|
||||
const { url, method = "POST", data, filename, extension = "xlsx" } = options;
|
||||
export async function requestBuffer(options: {
|
||||
url: string;
|
||||
method?: "GET" | "POST";
|
||||
data?: any;
|
||||
}): Promise<ArrayBuffer> {
|
||||
const { url, method = "POST", data } = options;
|
||||
const fullUrl = url.indexOf("http") === 0 ? url : baseUrl + url;
|
||||
const auth = bearerAuth();
|
||||
|
||||
@@ -493,7 +498,7 @@ export async function downloadFile(options: DownloadOptions): Promise<void> {
|
||||
const contentType = String(
|
||||
header["content-type"] || header.Content_Type || header.ContentType || "",
|
||||
);
|
||||
if (contentType.includes("application/json")) {
|
||||
if (contentType.includes("json")) {
|
||||
const text
|
||||
= typeof res.data === "string"
|
||||
? res.data
|
||||
@@ -513,19 +518,24 @@ export async function downloadFile(options: DownloadOptions): Promise<void> {
|
||||
notifyError("", message);
|
||||
throw markErrorNotified(new Error(message));
|
||||
}
|
||||
return res.data as ArrayBuffer;
|
||||
}
|
||||
|
||||
const fileName = `${filename}${timestamp()}.${extension}`;
|
||||
|
||||
/** 字节按指定文件名落盘:H5 走 blob+<a>;小程序/App 写本地目录后调起系统文档预览 */
|
||||
export async function saveArrayBuffer(bytes: ArrayBuffer, fileName: string): Promise<void> {
|
||||
// #ifdef H5
|
||||
// H5:blob + 隐藏 <a> 触发浏览器下载
|
||||
const downloadUrl = URL.createObjectURL(new Blob([res.data as ArrayBuffer]));
|
||||
const downloadUrl = URL.createObjectURL(new Blob([bytes]));
|
||||
const link = document.createElement("a");
|
||||
link.href = downloadUrl;
|
||||
link.download = fileName;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
link.remove();
|
||||
URL.revokeObjectURL(downloadUrl);
|
||||
// 浏览器读 blob 是异步任务:click 后立即 revoke 会让下载列表现「Failed - No file」,延迟释放
|
||||
setTimeout(() => {
|
||||
link.remove();
|
||||
URL.revokeObjectURL(downloadUrl);
|
||||
}, 3000);
|
||||
// #endif
|
||||
|
||||
// #ifndef H5
|
||||
@@ -544,7 +554,7 @@ export async function downloadFile(options: DownloadOptions): Promise<void> {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
fs.writeFile({
|
||||
filePath,
|
||||
data: res.data as ArrayBuffer,
|
||||
data: bytes,
|
||||
success: () => resolve(),
|
||||
fail: (err: any) => reject(new Error(err.errMsg || "写入文件失败")),
|
||||
});
|
||||
@@ -560,5 +570,15 @@ export async function downloadFile(options: DownloadOptions): Promise<void> {
|
||||
// #endif
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载并打开文件(默认按 Excel 处理):请求与落盘两段均已抽为公用函数,
|
||||
* 文件页的下载动作直接复用 requestBuffer + saveArrayBuffer
|
||||
*/
|
||||
export async function downloadFile(options: DownloadOptions): Promise<void> {
|
||||
const { url, method = "POST", data, filename, extension = "xlsx" } = options;
|
||||
const bytes = await requestBuffer({ url, method, data });
|
||||
await saveArrayBuffer(bytes, `${filename}${timestamp()}.${extension}`);
|
||||
}
|
||||
|
||||
// 导出(main.ts httpPlugin 注册用)
|
||||
export { httpInterceptor, httpRequestConfig };
|
||||
Reference in new issue
Block a user