解析通过formdata上传的节点服务器上的文件

时间:2018-05-08 19:38:50

标签: node.js

我正在使用formdata在客户端使用axios发布一些数据和文件,如下所示。

var formdata = new FormData();
formdata.append('title', shopTitle);
    formdata.append('ownedby', shopOwner);
    formdata.append('locality', shopLocality);
formdata.append('selectedFile', file);

axios.post('http://localhost:3000/businesses/', formdata, {headers: {
        'Content-Type': 'multipart/form-data'
      }})
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
          console.log('error occured..');
        console.log(error);
      });

现在在服务器上我使用formidable来解析formdata,如下所示 -

var express = require('express');
var bodyParser = require('body-parser');
var formidable = require('formidable');
var fs = require('fs');

// create express app
var app = express();
app.use(bodyParser.urlencoded({ extended: true }))
app.use(bodyParser.json());

app.post('/businesses', function(req, res){

var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files){
                        console.log('parsing fields..');
                        // selectedFile is found in fields and not in files
                        console.log(fields);
                        console.log('parsing files..');
                        console.log(files);                       
                        });
});

此处在服务器上,所选文件位于“字段”内,而不是“文件”中。 console.log(fields)语句将输出打印为

{   title: 'avani sweets',
  ownedby: 'avani',
  locality: 'sec 31',
  selectedFile: 'data:image/jpeg;base64,/9j/4AAQSkZ..............
}

现在我想在目录中保存此图像(由selectedFile表示)。我怎样才能做到这一点?如果能得到一些帮助,我将非常感激。感谢

1 个答案:

答案 0 :(得分:0)

根据我的理解,您通过提供回叫功能禁用了文件上传。如果您看看他们在GitHub-repo中的示例,而不是他们的README.MD https://github.com/felixge/node-formidable/blob/master/example/upload.js中的示例,您将采用一种非常不同的方法来处理上传。

...snip...
    } else if (req.url == '/upload') {
    var form = new formidable.IncomingForm(),
        files = [],
        fields = [];

    form.uploadDir = os.tmpdir();

    form
      .on('field', function(field, value) {
        console.log(field, value);
        fields.push([field, value]);
      })
      .on('file', function(field, file) {
        console.log(field, file);
        files.push([field, file]);
      })
      .on('end', function() {
        console.log('-> upload done');
        res.writeHead(200, {'content-type': 'text/plain'});
        res.write('received fields:\n\n '+util.inspect(fields));
        res.write('\n\n');
        res.end('received files:\n\n '+util.inspect(files));
      });
    form.parse(req);
  } else {

...snip...

如您所见,他们依赖设置上传目录,并使用事件监听器,而不是为.parse(...)提供回调,以获取文件和字段。在.on('file',...)侦听器中,他们将带有字段名称的文件推送到包含文件的数组中,因此您可以在文件系统中找到它们。

上传在.on('end',...)侦听器中完成,然后ypu可以启动您需要的任何其他作业,例如将字段和文件路径保存到数据库。

我希望这有助于您在项目中重回正轨!

修改

显然我误读了关于formdata的部分。我认为你的意思是multipart / formdata,因为网上有很多其他帖子。

如果您不能以传统格式发送axios,那么您需要做的是采用selectedFile的base64 endcoded部分并保存到新文件。

var raw = fields.selectedFile.split(";");
var imageType = raw[0].split("/")[1];
if(imageType == "jpeg"){
    imageType = "jpg";
}

var encodedFile = raw[1].split(",")[1];

require("fs").writeFile(`someFileName.${imageType}`, encodedFile, 'base64',(err) => {
    console.log(err);
});