Как решить кодировку при передаче файла из NodeJs Cloud Function? - PullRequest
0 голосов
/ 20 октября 2019

Я пытаюсь передать файл в корзину Firebase через облачную функцию nodeJS клиенту (браузеру). Клиент будет использовать 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
} 

Вот часть на стороне клиента:

export const getFile = (filename) =>{
   ...
   axios.get(fileUrl, config)
     .then(resp => {
         downloadFile(resp.data, filename, getMimeType(filename))
     }).catch(err => {
         console.log("getCurrentUserFile | err", err)
         reject(err)
     })

function downloadFile(data, filename, mimeType){
    var blob = new Blob([data], {type: mimeType});
    FileSaver.saveAs(blob, filename);
}

Ответы [ 2 ]

0 голосов
/ 21 октября 2019

Проблема была на стороне клиента, используя FileSaver.js и ничего с кодировкой.

После того, как я использовал это, это работало:

axios({
    url: fileUrl,
    method: 'GET',
    params:{...},
    responseType: 'blob', // <--important
}).then((resp) => {
     const url = window.URL.createObjectURL(new Blob([resp.data]));
     const link = document.createElement('a');
     link.href = url;
     link.setAttribute('download', filename);
     document.body.appendChild(link);
     link.click();
});

Кредит, причитающийся

0 голосов
/ 20 октября 2019

Я не уверен, как файл-заставка сохраняет файл, но я смог загрузить файлы с настройкой ниже и может помочь вам. 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>

Узлы:

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}!`))
...