From d8132fa9bf50584a5e2e3d3b30a27b2a6b3e5aa8 Mon Sep 17 00:00:00 2001 From: CaptainB Date: Mon, 7 Jul 2025 14:18:27 +0800 Subject: [PATCH] feat: add filename decoding from Content-Disposition header in exportFile function --- ui/src/request/index.ts | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/ui/src/request/index.ts b/ui/src/request/index.ts index 3ae9a9b4a..5723373ed 100644 --- a/ui/src/request/index.ts +++ b/ui/src/request/index.ts @@ -247,6 +247,19 @@ export const exportExcel: ( ) } +function decodeFilenameBrowser(contentDisposition: string) { + // 提取并解码 Base64 部分 + const base64Part = contentDisposition.match(/=\?utf-8\?b\?(.*?)\?=/i)?.[1]; + if (!base64Part) return null; + + // 使用 atob 解码 Base64 + const decoded = decodeURIComponent(escape(atob(base64Part))); + + // 提取文件名 + const filenameMatch = decoded.match(/filename="(.*?)"/i); + return filenameMatch ? filenameMatch[1] : null; +} + export const exportFile: ( fileName: string, url: string, @@ -258,7 +271,22 @@ export const exportFile: ( params: any, loading?: NProgress | Ref, ) => { - return promise(request({ url: url, method: 'get', params, responseType: 'blob' }), loading).then( + return promise(request({ + url: url, + method: 'get', + params, + responseType: 'blob', + transformResponse: [function (data, headers) { + // 在这里可以访问 headers + // const contentType = headers['content-type']; + const contentDisposition = headers['content-disposition']; + // console.log('Content-Type:', contentType); + // console.log('Content-Disposition:', decodeFilenameBrowser(contentDisposition)); + // 如果没有提供文件名,则使用默认名称 + fileName = decodeFilenameBrowser(contentDisposition) || fileName; + return data; // 必须返回数据 + }] + }), loading).then( (res: any) => { if (res) { const blob = new Blob([res], {