Angular对接NodeJS下载CSV文件内容为[object Object]问题咨询
故障原因
下载得到的CSV文件仅显示[object Object]由以下代码问题共同导致:
- 后端接口将读取到的文件Buffer包裹在JSON对象
{file: buffer}中返回,没有直接输出二进制文件流,实际响应内容为JSON格式而非原始CSV内容 - Angular前端HTTP请求默认按JSON格式解析响应,未指定接收二进制数据类型,拿到的返回值是普通JS对象,传入Blob构造函数时会被自动序列化为
[object Object]字符串写入文件 - 组件中
subscribe括号位置错误,错误回调、完成回调写在了subscribe方法外部,无法正常捕获请求异常、触发完成提示
修复方案
1. NodeJS后端接口修改
不要将文件内容包裹在对象中返回,推荐使用Express原生提供的res.download方法处理文件下载,自动设置正确的响应头,同时使用path模块拼接路径避免跨平台兼容问题:
const path = require('path'); const fs = require('fs'); router.get('/downloadCsv/', (req,res) => { const projectId = req.query.projectId; const fileName = req.query.fileName; const basePath = path.join('searchResults', `project_${projectId}`, 'OutputsCsv'); const fullPath = path.join(basePath, fileName); // 生产环境请在此处增加路径合法性校验,拦截包含../的路径遍历请求,防止越权读取服务器敏感文件 if (!fs.existsSync(fullPath)) { return res.status(404).send('File not found'); } // 直接返回文件,无需手动包装为对象 res.download(fullPath, fileName, { headers: { 'Content-Type': 'text/csv; charset=utf-8' } }); })
2. Angular服务层修改
发起HTTP请求时指定responseType: 'blob',告诉HTTP客户端不要按JSON解析响应,直接返回二进制Blob对象:
import { HttpParams } from '@angular/common/http'; public downloadCsv(projectId: string | number, fileName: string){ const params = new HttpParams() .set("projectId", projectId) .set("fileName", fileName); // 指定响应类型为blob,无需设置泛型参数 return this.http.get(`${environment.baseUrl}/search/downloadCsv`, { params, responseType: 'blob' }); }
3. Angular组件层修改
修正subscribe的语法错误,服务层已经直接返回Blob类型,无需手动再包装一层Blob:
import { saveAs } from 'file-saver'; download() { const fileName = `project_${this.projectId}_output_datas.csv`; this.searchService.downloadCsv(this.projectId, fileName).subscribe({ next: (fileBlob: Blob) => { saveAs(fileBlob, fileName); }, error: (error: any) => { console.log('Error downloading the file', error); }, complete: () => { console.info('File downloaded successfully'); } }); }
注意:如果下载后CSV打开出现中文乱码,可以在后端返回文件时在CSV内容最前面加上BOM头
\uFEFF,兼容Excel的默认编码识别。
内容的提问来源于stack exchange,提问作者Julien Martin
相关产品推荐
相关产品推荐

