【Vue3】下载zip文件损坏的问题
需求:
需要在vue3上实现Asp.net Web API 下载zip包的功能,本身需求很简单,但是中间遇到了问题,记录一下。
问题:
下载的zip包和后端的zip包大小不一致,后端生成的zip 61kb,下载之后变成了100kb,并且打开就提示损坏,也无法正常解压。
解决:
直接先放后端代码,对外提供接口,返回形式使用FileStreamResult,这个一般不会有问题。
后端代码实现
[HttpPost, Route("downloadalarmexcel")]
public FileStreamResult DownloadAlarmZipFile([FromBody] string mode)
{
FileStreamResult fileResult = _alarmService.DownloadAlarmZipFile(mode);
return fileResult;
}
public FileStreamResult DownloadAlarmZipFile(string fileName)
{
string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "File", fileName);
if (!File.Exists(filePath))
{
throw new FileNotFoundException("找不到指定的文件", filePath);
}
var memory = new MemoryStream();
using (var stream = new FileStream(filePath, FileMode.Open))
{
stream.CopyTo(memory);
}
memory.Position = 0;
return new FileStreamResult(memory, "application/zip")
{
FileDownloadName = fileName,
EnableRangeProcessing = true // 支持断点续传
};
}
关键在于前端的文件接收,必须要在请求时加上
responseType: 'blob'
这个如果没有设置下载的文件将出现损坏的问题
// 导出excel
const handleExport = async () => {
try {
state.loading = true
const fileName = 'xxx.zip';
var AxiosRequestConfig = {
responseType: 'blob'
}
let downloadRes = await getAPI(AlarmApi).apiAlarmDownloadalarmexcelPost(fileName,AxiosRequestConfig) as any;
// 3. 处理文件下载
console.log(downloadRes);
const blob = new Blob([downloadRes.data], {
type: 'application/zip;charset=utf-8'
})
// 检查blob是否有效
if (blob.size === 0) {
throw new Error('文件内容为空')
}
const url = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.download = fileName // 使用服务器返回的文件名
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(url)
ElMessage.success('导出成功')
} catch (error) {
console.error('导出失败:', error)
ElMessage.error('导出失败')
} finally {
state.loading = false
}
};