React+Node应用通过Node代理请求REST API实现浏览器ZIP下载方案咨询
完整实现方案
问题原因说明
你之前下载的压缩包内容异常,核心是两处配置缺失:
- Node侧请求上游API时未指定二进制流响应格式,axios默认按文本解析导致二进制数据被转码
- React侧请求Node接口时未指定Blob类型响应,同样会把二进制数据转成文本/Base64格式
Node侧代码修改
如果前端和Node服务端口不同,先安装cors依赖处理跨域,再修改接口代码:
const cors = require('cors'); app.use(cors()); app.post('/descarcare', async function(req, res) { try { const id = req.body.id2; // 替换为真实上游接口,传入对应id参数 const upstreamResponse = await axios.get(`http://restapi.com/aaa?id=${id}`, { // 关键配置:指定响应类型为流,直接读取二进制数据不做解析 responseType: 'stream' }); // 设置响应头,告知浏览器这是需要下载的zip文件 res.setHeader('Content-Type', 'application/zip'); res.setHeader('Content-Disposition', `attachment; filename="download_${id}.zip"`); // 直接把上游返回的数据流转发给客户端,无需额外转码处理 upstreamResponse.data.pipe(res); } catch (err) { console.error('下载失败', err); res.status(500).send('下载失败'); } });
React侧代码修改
调整axios请求配置,拿到响应后触发浏览器自动下载:
$("#example tbody").on('click', '#buton123', function() { const id = response.data.mesaje[$(this).closest('tr').index()].id; const article2 = {id2: id}; axios.post('http://localhost:3001/descarcare', article2, { // 关键配置:指定响应类型为Blob,接收二进制文件流 responseType: 'blob' }).then((response) => { // 生成Blob对象 const blob = new Blob([response.data], {type: 'application/zip'}); // 创建临时下载链接 const downloadUrl = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = downloadUrl; // 自定义下载的文件名 a.download = `文件_${id}.zip`; document.body.appendChild(a); a.click(); // 清理临时生成的资源 window.URL.revokeObjectURL(downloadUrl); document.body.removeChild(a); }).catch(err => { console.error('下载请求失败', err); }) });
注意事项
- 若Node服务已经配置了跨域规则,可以不用额外引入cors中间件
- 上游接口如果需要鉴权(比如请求头带Token),直接在Node侧的axios请求的headers字段中添加即可,不会暴露给前端
- 该方案支持大文件下载,采用流式传输不会占用Node服务的过多内存
内容的提问来源于stack exchange,提问作者RamonS
相关产品推荐
相关产品推荐

