如何从NodeJs Cloud Function传递管道文件时解决编码?

问题描述 投票:0回答:1

我正在尝试通过nodeJS云功能将Firebase存储桶中的文件通过管道传输到客户端(浏览器)。客户端将使用file-saver.js在浏览器上开始下载。

这对于text/plain MIME类型效果很好,但会生成带有图像和PNG的损坏文件。问题在于编码,因为我可以看到到达客户端的数据未正确编码。

这是带有图像的客户端响应示例:

data: "�PNG↵↵IHDR%�*���sBIT|d�...

我应如何正确地将文件传回以保持正确的编码?

这里是当前的云功能:

const filesBucket = admin.storage().bucket(FILES_BUCKET_NAME);

function getFile(fileName, res){
  const filePath = fileName
  const file = filesBucket.file(filePath)

  res.setHeader('Content-Type', getMimeType(fileName));
  res.setHeader('Content-Disposition', 'attachment; filename='+fileName);

  file.createReadStream()
    .on('error', err => {
        // not good
    })
    .on('response', function(response) {
        // ok
    })
    .on('end', function() {
        // The file is fully downloaded.
    })
    .pipe(res); // pipe the file back to client
} 
javascript node.js encoding stream pipe
1个回答
0
投票

我不确定文件保存程序如何保存文件,但是我能够通过以下设置下载文件,可能会对您有所帮助。index.html

<!DOCTYPE html>
<html>

<body onload="myFunction()">

    <h1>Hello World!</h1>

    <script>
        function myFunction() {

            var xhttp = new XMLHttpRequest();
            xhttp.onreadystatechange = function() {
                if (this.readyState == 4 && this.status == 200) {

                    var contentType = this.getResponseHeader('Content-Type')
                    var fileExtention;
                    if (contentType) {

                        fileExtention = contentType.split('/')[1]

                    }

                    //console.log(this.responseText)
                    var a = document.createElement("a");
                    document.body.appendChild(a);
                    a.style = "display: none";

                    var url = window.URL.createObjectURL(this.response);
                    a.href = url;
                    a.download = "demo." + fileExtention
                    a.click();
                    window.URL.revokeObjectURL(url);
                    a.remove();
                }
            };
            xhttp.responseType = 'blob'
            xhttp.open("GET", "http://localhost:3000/getfile", true);
            xhttp.send();

        }
    </script>

</body>

</html>

Nodejs:

const express = require('express')
const fs = require('fs')
const app = express()
const port = 3000

app.use(express.static('public'))

app.get('/getfile', (req, res) => {
    res.setHeader('Content-Type', 'image/png');
    //res.setHeader('Content-Disposition', 'attachment; filename='+'test.png');
    fs.createReadStream('./demo.png').pipe(res)
})

app.listen(port, () => console.log(`Example app listening on port ${port}!`))
© www.soinside.com 2019 - 2024. All rights reserved.