feat(chat): ChatTimeline 导出按钮 + 修复 downloadBlob 文件名丢失(Content-Disposition)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -42,16 +42,17 @@ export function getJson<T>(url: string, params?: Record<string, unknown>): Promi
|
||||
return http.get(url, { params }) as unknown as Promise<T>
|
||||
}
|
||||
|
||||
/** 以 blob 下载(用于 HTML 导出等二进制/文本附件下载)。返回固定文件名(响应拦截器丢失 content-disposition 头)。 */
|
||||
/** 以 blob 下载(HTML 导出等附件)。从 Content-Disposition 取文件名(绕开 http 的 (r)=>r.data 解包拦截器)。 */
|
||||
export async function downloadBlob(
|
||||
url: string,
|
||||
params?: Record<string, unknown>,
|
||||
): Promise<string> {
|
||||
const res = await http.get(url, { params, responseType: 'blob' })
|
||||
const blob = res as unknown as Blob
|
||||
// 从响应头取文件名(拦截器只解包 body,需用 raw 拦截;此处 res 已是 blob,header 丢失 → 用固定名)
|
||||
const filename = 'chat-export.html'
|
||||
const objUrl = URL.createObjectURL(blob)
|
||||
// 裸 axios(补 /api 前缀)拿全响应(含 headers),不经 http 拦截器
|
||||
const res = await axios.get(`/api${url}`, { params, responseType: 'blob' })
|
||||
const cd = (res.headers['content-disposition'] as string) || ''
|
||||
const m = /filename="?([^";]+)"?/i.exec(cd)
|
||||
const filename = m ? m[1] : 'chat-export.html'
|
||||
const objUrl = URL.createObjectURL(res.data as Blob)
|
||||
const a = document.createElement('a')
|
||||
a.href = objUrl
|
||||
a.download = filename
|
||||
|
||||
Reference in New Issue
Block a user