如何从React调用连接Dataverse的Node.js API实现文件下载?
解决方案
后端处理方案
如果可以修改Node.js API,直接返回文件流是最稳妥的方式,浏览器会自动触发下载:
- 从Dataverse拿到包含
documentbody的文件对象后,把base64编码的documentbody解码成Buffer - 设置响应头,指定文件类型和下载用的文件名
- 把Buffer作为响应发送给前端
示例代码(基于Express框架):
app.get('/download-file/:id', async (req, res) => { try { // 替换成你调用Dataverse获取文件的实际逻辑 const fileObj = await getDataverseFile(req.params.id); // 将base64字符串解码为Buffer const fileBuffer = Buffer.from(fileObj.documentbody, 'base64'); // 设置响应头,告诉浏览器这是要下载的文件 res.setHeader('Content-Type', fileObj.mimetype); res.setHeader('Content-Disposition', `attachment; filename="${fileObj.filename}"`); // 发送文件内容 res.send(fileBuffer); } catch (err) { res.status(500).send('下载失败'); } });
前端React按钮直接请求这个接口就行:
<button onClick={() => window.open('/download-file/1', '_blank')}>下载文件</button>
前端处理方案
如果不想改动后端,前端可以直接处理返回的base64字符串生成下载:
- 点击按钮时调用API拿到文件对象
- 把base64格式的
documentbody转换成Blob对象 - 创建临时URL指向Blob,通过隐藏的a标签触发下载
- 下载完成后释放临时URL资源,避免内存泄漏
示例React组件代码:
import { useState } from 'react'; function FileDownloadButton() { const handleDownload = async () => { try { // 调用你的API获取文件数据 const response = await fetch('/api/get-file/1'); const fileObj = await response.json(); // 将base64字符串转换为Blob const byteCharacters = atob(fileObj.documentbody); const byteNumbers = Array.from(byteCharacters, char => char.charCodeAt(0)); const byteArray = new Uint8Array(byteNumbers); const blob = new Blob([byteArray], { type: fileObj.mimetype }); // 创建临时下载链接 const downloadUrl = URL.createObjectURL(blob); const aTag = document.createElement('a'); aTag.href = downloadUrl; aTag.download = fileObj.filename; document.body.appendChild(aTag); // 模拟点击触发下载 aTag.click(); // 清理临时资源 document.body.removeChild(aTag); URL.revokeObjectURL(downloadUrl); } catch (err) { alert('下载失败,请重试'); } }; return <button onClick={handleDownload}>下载文件</button>; } export default FileDownloadButton;
内容的提问来源于stack exchange,提问作者Jose Bernardo
相关产品推荐
相关产品推荐

