文件"/>
使用 NodeJS 和 ReactJS 下载 ZIP 文件
我正在尝试使用 ReactJS 客户端下载一个 zip 文件。 zip 文件是在后端 (Node JS) 创建的。
我的 React 客户端执行以下操作:
{this.state.selectedRows.length > 0 &&
<>
<Tooltip title="Baixar arquivos" arrow>
<IconButton
onClick={() => {
const dcs = (!!this.state.selectedRows && this.state.selectedRows.length === 0) ? this.state.fls.map(f => f.doc_id ) : this.state.selectedRows
this.props.api.post('/mediateca/downloadzipfile', { docs: dcs }).then(r => {
this.setState({ selectedRows: [] })
var blob = new Blob([r], { type: "application/octet-stream" });
saveAs(blob, "example.zip")
})
}}>
<FileDownload />
</IconButton>
</Tooltip>
<D size="0.5rem" />
</>
}
如果我打印帖子响应(“console.log(r)”),我会看到类似“PK<0x03><0x04><0x14>...”的字符串,但更长(它似乎是 zip 文件的 ASCII 序列)。我制作了 238.2 kB 的下载 example.zip 文件。但是,没有 zip 应用程序能够打开它。
此外,在后端 Node JS 端,我有触发此方法的 post 路由:
async downloadZIPfile(ctx) {
let u = await ctx.auth.getUser()
Log.create(!!u ? u.email : "null", ctx.request.url())
const { docs } = ctx.request.all()
const rdocs = !!docs && docs.length > 0 ? docs : []
//Recupera os pdfs do banco de dados e salva um zip no /tmp
if(rdocs.length > 0){
var zip = new AdmZip()
for(let x in rdocs){
const doc = await Documentos.findOne({ where: { id: rdocs[x] } })
if (!!doc) {
const file = await Arquivos.findOne({ where: { id: doc.arquivo_id } })
var filePath = "/tmp/"+rdocs[x]+".pdf"
zip.addFile(rdocs[x]+".pdf",file.binario)
}
}
var data = zip.toBuffer()
var fileName = "flavio.zip"
zip.writeZip("/tmp/"+fileName)
ctx.response.header('Content-Type', 'application/octet-stream')
ctx.response.header('Content-Disposition', `attachment; filename=${fileName}`)
ctx.response.header('Content-Length', data.length)
ctx.response.send(data);
}
else {
ctx.response.status(404).send()
}
return { status: 'ok' }
}
}
注意这个方法保存了一个flavio.zip 130,8KB的文件用于调试。它可以通过任何 zip 应用程序正确打开。
那么,我的 React 客户端 POST 响应有什么问题?
我正在尝试使用 ReactJS 客户端下载一个 zip 文件。 zip 文件是在后端 (Node JS) 创建的。
回答如下:问题可能出在您如何处理 ReactJS 客户端中的响应。不要直接将响应数据传递给 saveAs 函数,您应该从响应数据创建一个新的 Blob 对象,然后将其传递给 saveAs 函数。
this.props.api.post('/mediateca/downloadzipfile', { docs: dcs }, { responseType: 'arraybuffer' }).then(response => {
const blob = new Blob([response.data], { type: 'application/octet-stream' })
saveAs(blob, 'example.zip')
})
在此代码中,我们将 responseType 选项设置为“arraybuffer”,以便响应数据作为 ArrayBuffer 对象返回,然后我们可以使用它来创建新的 Blob 对象。我们将这个 Blob 对象和所需的文件名传递给 saveAs 函数以触发下载。
更多推荐
使用 NodeJS 和 ReactJS 下载 ZIP 文件
发布评论