NodeJS:将通过HTTP-POST发送的图像保存为流到文件系统

时间:2019-07-15 17:33:25

标签: node.js

以下代码,将图像以流形式保存到通过POST发送的文件系统中,但是无论我尝试使用哪个图像,保存的文件都是无效的。

enter image description here

有人能告诉我为什么此代码不起作用吗?

var http = require('http');
var fs = require('fs');

http.createServer(function (req, res) {
  res.setHeader("Access-Control-Allow-Origin", "*")
  res.setHeader("Content-Type", 'text/html');

  var imagedata = ''
  req.setEncoding('binary')

  req.on('data', (chunk) => {
    console.log(chunk);
    imagedata += chunk
  })

  req.on('end', function(){
     fs.writeFile('logo.png', imagedata, 'binary', function(err){
            if (err) throw err
            console.log('File saved.')
        })
  })
}).listen(3000);

[已添加/更新] ,这是通过AXIOS HTTP库将请求发送到VueJS中的Node后端的前端代码。

发送请求(VueJS-Axios)

<template>
  <div id="app">
    <input type="file" name="file" @change="getFile">
    <button @click="uploadFile">Upload file</button>
  </div>
</template>

<script>

import axios from 'axios'

export default {
  name: "App",

  data() {
    return {
      selectedFile: null
    }
  },

  methods: {
    getFile() {

      let file = event.target.files[0]
      this.selectedFile = file
    },
    uploadFile() {
        let fd = new FormData()
        fd.append('file', this.selectedFile)
        axios({
            method: 'post',
            url: 'http://localhost:3000/axiosFile',
            data: fd,
            config: { headers: {'Content-Type': 'multipart/form-data' }}
        })
          .then(res => {
              console.log(res);
          })
    }
  }
}
</script>

POST chunk data in console

1 个答案:

答案 0 :(得分:2)

您可能会遇到问题,因为您正在将这些块连接到一个字符串。除非将数据编码为Base64或HEX编码,否则将二进制数据编码为字符串会使数据乱码。

您可以简单地将大块保留为缓冲区,然后将所有缓冲区连接起来,然后再将数据写入文件中:

http.createServer((req, res) => {

    let length = 0;
    const chunks = [];
    req.on('data', (chunk) => {
        chunks.push(chunk);
        length += chunk.length;
    });

    req.on('end', () => {
        const imagedata = Buffer.concat(chunks, length);
        fs.writeFile('logo.png', imagedata, 'binary', (err) => {
            if (err) {
                console.error(err);
                // Send error response...
            } else {
                console.log('File saved.');
                // Send success response...
            }
        });
    });
}).listen(3000);

或者您可以利用流管道的优势,让流为您完成工作:

http.createServer((req, res) => {
    const imageFile = fs.createWriteStream('logo.png');
    req.pipe(imageFile)
        .on('error', (err) => {
            console.error(err);
            // Send error response...
        })
        .on('finish', () => {
            console.log('File saved.');
            // Send success response...
        });
}).listen(3000);

在客户端,请求看起来像这样:

axios({
    method: 'post',
    url: 'http://localhost:3000/axiosFile',
    data: this.selectedFile
}).then(res => console.log(res)).catch(err => console.error(err));