Vue+Axios调用.NET Core API下载二进制文件损坏大小翻倍问题
问题原因
你遇到的二进制文件下载损坏、体积翻倍问题和后端接口无关——Postman能正常下载290KB的PDF已经证明后端逻辑完全正确。问题出在Axios的默认响应处理逻辑:
Axios默认将所有响应当作UTF-8编码的文本字符串解析,处理二进制流(PDF、Excel、图片)时,会对原始字节做UTF-8转码,不符合UTF-8规则的字节会被替换成占位字符,直接破坏文件结构,最终导致文件体积变大、内容损坏。txt、csv这类纯文本文件本身是UTF-8编码,所以转码不会产生异常。
修复方法
只需要在Axios请求配置里显式指定responseType: 'blob',告诉Axios直接返回二进制Blob对象,不要做文本转码即可,两种实现方案的修正代码如下:
基于js-file-download的修正版本
import fileDownload from "js-file-download"; const downloadAttachment = async (attachmentId, filename) => { try { const result = await api.get(`/api/Attachments/DownloadAttachment/${attachmentId}`, { responseType: 'blob' // 核心配置,必须添加 }); fileDownload(result.data, filename, result.headers["content-type"]); } catch (error) { console.error(error); return error; } }
原生实现的修正版本
你之前的原生实现还有个隐藏问题:调用window.location.assign后立刻执行revokeObjectURL会导致浏览器还没读取完Blob就释放内存,可能触发下载失败,建议用a标签触发下载,延迟释放内存:
const downloadAttachment = async (attachmentId, filename) => { try { const result = await api.get(`/api/Attachments/DownloadAttachment/${attachmentId}`, { responseType: 'blob' // 核心配置,必须添加 }); const blob = new Blob([result.data], { type: result.headers["content-type"] }); const exportUrl = URL.createObjectURL(blob); const downloadLink = document.createElement('a'); downloadLink.href = exportUrl; downloadLink.download = filename; document.body.appendChild(downloadLink); downloadLink.click(); document.body.removeChild(downloadLink); // 延迟100ms再释放Blob内存,避免下载中断 setTimeout(() => URL.revokeObjectURL(exportUrl), 100); } catch (error) { console.error(error); return error; } }
验证点
修复后你打印返回Blob的size值,会和接口响应头的Content-Length数值完全一致,下载的PDF、Excel、图片等二进制文件都可以正常打开。
内容的提问来源于stack exchange,提问作者Carel
相关产品推荐
相关产品推荐

