Angular 13接收后端BLOB转PDF时类型转换错误求助
问题根源
你的前端HttpClient.post参数顺序和配置完全错误,导致Angular默认将响应解析为JSON,这就是控制台报错的核心原因。同时后端请求Jasper Reports API时,也存在二进制数据获取的配置漏洞。
解决方案
1. 修复前端API调用代码
Angular HttpClient.post的参数顺序为:请求URL → 请求体 → 配置选项。你当前错误地将responseType作为请求体传递,params也未放在正确的配置位置。修正后的代码如下:
// 修正getReport方法 getReport(params: { acc_id: string; start_date: string; end_date: string; sage_num: string }) { // 参数放在请求体中(和后端接收逻辑对应),配置responseType为blob return this.http.post(`${environment.apiUrl}/api/accounts/report`, { params }, { responseType: 'blob' as 'json' } // as 'json'是TypeScript类型兼容处理技巧 ); } // 修正订阅逻辑 pdfExportBtn(e:any){ const params={"acc_id":"18785","start_date":"2022/05/01, 00:00:00","end_date":"2022/06/01, 00:00:00","sage_num":"12341234"}; this.getReport(params).subscribe((response: Blob) => { const downloadLink = document.createElement('a'); downloadLink.target = '_self'; const fileName = `${acc_name} Transaction Summary ${date1} to ${date2}.pdf`; const data = window.URL.createObjectURL(response); downloadLink.href = data; downloadLink.download = fileName; document.body.appendChild(downloadLink); downloadLink.click(); // 清理URL对象避免内存泄漏 window.URL.revokeObjectURL(data); document.body.removeChild(downloadLink); }); }
2. 修复后端Jasper API调用逻辑
后端使用request库获取报表时,必须设置encoding: null才能拿到二进制Buffer(否则response.body会被转成字符串,导致PDF损坏),同时要设置正确的响应头:
app.post('/api/accounts/report',(req,res)=>{ const { acc_id, start_date, end_date, sage_num } = req.body.params; const request = require("request").defaults({ jar: true }); // 登录Jasper Server request.post({ url: jasper_login, qs: { j_username:jasper_usr, j_password:jasper_pwd } }, (err, resp, body) => { if(err) { console.error(err); return res.status(500).send('登录Jasper服务器失败'); } // 请求报表时设置encoding: null获取二进制数据 request.get({ url: jasper_hst, encoding: null // 关键配置:确保返回Buffer而非字符串 }, (error, response, body1) => { if (error || response.statusCode !== 200) { console.error(error || `报表请求失败,状态码:${response.statusCode}`); return res.status(500).send('生成报表失败'); } // 设置正确的PDF响应头 res.set({ 'Content-Type': 'application/pdf', 'Content-Disposition': `inline; filename="report.pdf"` }); res.send(body1); // body1是Buffer,直接发送即可 }) }) });
关键说明
- 前端
responseType必须在options对象中配置,TypeScript环境下需加as 'json'绕过类型校验。 - 后端
request.get必须添加encoding: null,否则二进制数据会被转成UTF-8字符串,导致PDF文件损坏。 - 后端返回时明确设置
Content-Type: application/pdf,让浏览器直接识别文件类型。
内容的提问来源于stack exchange,提问作者az-lt
相关产品推荐
相关产品推荐

