ReactJS跨系统下载Node.js后端Blob文件内容显示[object Object]的解决方法
解决React中下载Blob文件显示[object Object]的问题
我来帮你分析下问题所在,以及对应的解决方案:
问题根源
你下载的文件内容显示[object Object],核心原因是你并没有拿到真正的Blob二进制数据。虽然后端服务器端的对象里包含Blob,但当它通过HTTP接口返回时,Blob会被序列化成一个普通的JavaScript对象(就是你看到的带有Symbol(type)和Symbol(buffer)的结构),而前端解析JSON后,这个对象已经不是可直接使用的Blob实例了。当你把这个普通对象传入new Blob([...])时,JS会自动把对象转成字符串[object Object],这就是你看到的文件内容。
解决方案
根据后端的返回方式,有两种可行的处理方案:
方案一:后端直接返回Blob文件(推荐)
如果可以调整后端逻辑,让它直接返回Blob二进制数据,同时通过响应头传递文件名,这是最简洁的方式:
- 后端需要设置响应头:
Content-Type: text/html(匹配你的文件类型)Content-Disposition: attachment; filename="newfile123.html"(传递文件名)
- 前端请求时要配置
responseType: 'blob',确保拿到的是原始Blob数据(以axios为例):
// 假设你用axios发送请求 axios.get('/your-api-url', { responseType: 'blob' // 关键配置:告诉axios直接返回Blob }) .then(response => { const blob = response.data; const link = document.createElement('a'); // 创建Blob的临时URL const blobUrl = window.URL.createObjectURL(blob); link.href = blobUrl; // 可以从响应头提取文件名,或者用你预先获取的name const filename = response.headers['content-disposition']?.split('filename=')[1].replace(/"/g, '') || name; link.setAttribute('download', filename); // 触发下载 document.body.appendChild(link); link.click(); // 清理资源 document.body.removeChild(link); window.URL.revokeObjectURL(blobUrl); // 必须释放URL对象,避免内存泄漏 });
方案二:后端返回包含Base64编码的JSON
如果后端无法直接返回Blob,需要把Blob转成Base64字符串放在JSON里返回:
- 后端调整:将Blob转成Base64编码字符串,返回的JSON结构类似:
{ "success": true, "message": "Blob retrieved successfully", "blobBase64": "这里是Base64编码的字符串", "mimeType": "text/html", "name": "newfile123.html" } - 前端将Base64转成Blob再下载:
// 假设response.data是后端返回的JSON对象 const { blobBase64, mimeType, name } = response.data; // 将Base64字符串转成Uint8Array const byteCharacters = atob(blobBase64); const byteNumbers = Array.from(byteCharacters, char => char.charCodeAt(0)); const byteArray = new Uint8Array(byteNumbers); // 创建Blob对象 const blob = new Blob([byteArray], { type: mimeType }); // 下载逻辑和之前一致 const link = document.createElement('a'); const blobUrl = window.URL.createObjectURL(blob); link.href = blobUrl; link.setAttribute('download', name); document.body.appendChild(link); link.click(); document.body.removeChild(link); window.URL.revokeObjectURL(blobUrl);
为什么你的原代码不行?
原代码中const blob = new Blob([response.data.blob]);里的response.data.blob是一个普通JS对象(JSON解析后的结果),不是真正的Blob实例。当你把对象传入Blob构造函数时,JS会调用对象的toString()方法,得到[object Object],所以生成的Blob内容就是这个字符串,下载后自然显示这个内容。
内容的提问来源于stack exchange,提问作者i_code
相关产品推荐
相关产品推荐

