.NET Core Web API返回CSV在ReactJS中无法触发下载如何解决?
解决方案
核心原理
axios 基于 XMLHttpRequest 发起请求,浏览器不会像直接访问接口地址那样自动识别 Content-Disposition: attachment 响应头触发下载,需要前端手动处理返回的二进制流生成可下载文件。
具体修改步骤
1. 调整axios请求配置
给axios请求添加responseType: 'blob'配置,让返回的CSV内容以二进制Blob对象形式接收,避免中文乱码或格式错误。
修改后的接口请求代码如下:
export const getExportedValues = async (projectId: string, bookId: string) => { if (projectId && bookId) { const finalUrl: string = `${getEnvConfig().projectsAPIUrl}/document/generatecsv/project/${projectId}/bookID/${bookId}`; let resp: any = await axios({ method: AxiosMethods.GET, url: finalUrl, responseType: 'blob' // 新增这一行配置 }).catch(err => errorFunction(err)) if (!resp?.data?.error) { // 新增下载逻辑调用 triggerDownload(resp) return true } } return false }
2. 新增下载触发逻辑
添加triggerDownload方法,通过动态创建a标签模拟浏览器点击下载行为:
const triggerDownload = (response: any) => { // 生成CSV对应的Blob对象 const blob = new Blob([response.data], { type: 'text/csv;charset=utf-8;' }) // 创建临时下载链接 const downloadUrl = window.URL.createObjectURL(blob) const link = document.createElement('a') link.href = downloadUrl // 优先从响应头取后端定义的文件名,取不到则用默认值 let fileName = 'Pdrd.csv' const disposition = response.headers['content-disposition'] if (disposition && disposition.indexOf('filename=') !== -1) { fileName = decodeURIComponent(disposition.split('filename=')[1].replace(/"/g, '')) } link.setAttribute('download', fileName) // 模拟点击触发下载 document.body.appendChild(link) link.click() // 清理临时对象释放内存 document.body.removeChild(link) window.URL.revokeObjectURL(downloadUrl) }
注意事项
如果需要从响应头读取后端设置的文件名,需要在.NET Core后端的CORS配置中添加暴露Content-Disposition头的配置,示例如下:
builder.Services.AddCors(options => { options.AddPolicy("CorsPolicy", policy => { policy.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader() .WithExposedHeaders("Content-Disposition"); // 新增这一行配置 }); });
内容的提问来源于stack exchange,提问作者Programmerzzz
相关产品推荐
相关产品推荐

