最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

使用 NodeJS 和 ReactJS 下载 ZIP 文件

网站源码admin30浏览0评论

使用 NodeJS 和 ReactJS 下载 ZIP 文件

使用 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 函数以触发下载。

发布评论

评论列表(0)

  1. 暂无评论