req.form不是实例化的多方表单对象

Wil*_*ger 1 upload middleware multipart node.js express

我正在使用具有多部分中间件的快速节点框架.设置multipart defer: true选项使我可以访问req.form路径,但它似乎不是多方Form对象的有效实例.它只是一个普通的旧JS对象.

问题是我无法使用表单对象上的multiparty文档中概述的功能.收听事件,解析表单等都不起作用.

我使用它作为建议而不是使用express的折旧bodyParser():

app.use(express.urlencoded());
app.use(express.json());
app.use(express.multipart({ limit: '900mb', defer: true }));
Run Code Online (Sandbox Code Playgroud)

在我的路线:

app.post('/api/videos/upload', isLoggedIn, function(req, res) {
    var form = req.form;
    form.on('progress', function(bytesReceived, bytesExpected) {
        console.log(bytesReceived + ' / ' + bytesExpected);
    });
Run Code Online (Sandbox Code Playgroud)

我在日志中得不到有关进展的任何信息.我看到的所有例子都假设这个表单对象是真正的交易而不仅仅是数据对象.他们有什么不同的做法?我错过了什么?

我已经看到建议编写我自己的中间件直接使用multiparty的解决方案.我考虑过这个,但是我在不同路径上使用多部分中间件用于不需要这种控制级别的其他形式.是否可以使用multipart并编写我自己的中间件只是为了上传?

如果我要走下一个兔子洞,我会解释我的最终目标.我想在上传开始之前检查预期的字节,这样我就可以立即将其踢回前端.没有理由用户在发现文件太大之前应该等待900MB上传.如果有人对如何实现其他方式有任何见解请分享.

Ger*_*ndo 5

当您使用express.multipart(),你仍然使用过时的express.bodyParser()解释这里.

因此,我们必须直接替换以下解析器/中间件之一:

  1. 强大

  2. connect-multiparty或[multiparty]

  3. connect-busboy或busboy

我直接选择了多方 API.

在你的路线:

var multiparty = require('multiparty'),
    fs = require('fs'),
    uuid = require('node-uuid');

app.post('/api/videos/upload', function(req, res) {

  var size = '';
  var file_name = '';
  var destination_path = '';

  // Instatiation in order to use the API options multiparty.Form({options})
  var form = new multiparty.Form();

  form.on('error', function (err) {
    console.log('Error parsing form: ' + err.stack);
  });

  form.on('part', function (part) {
    if (!part.filename)
        return;
    size = part.byteCount;
    file_name = part.filename;
  });

  form.on('file', function (name, file) {
    var temporal_path = file.path;
    var extension = file.path.substring(file.path.lastIndexOf('.'));
    destination_path = './public/uploads/' + uuid.v4() + extension;
    var input_stream = fs.createReadStream(temporal_path);
    var output_stream = fs.createWriteStream(destination_path);
    input_stream.pipe(output_stream);

    input_stream.on('end',function() {
        fs.unlinkSync(temporal_path);
        console.log('Uploaded : ', file_name, size / 1024 | 0, 'kb', file.path, destination_path);
    });
  });

  form.on('close', function(){
    res.end('Uploaded!');
  });

  form.parse(req);

});
Run Code Online (Sandbox Code Playgroud)

你在前端使用了什么?为了在上传之前获取文件的大小,您可以使用AngularJS进行即时双向数据绑定.有一个很好的角度文件上传模块,可以与上面的实现一起使用.但是,如果要为multipart/form-data编写自己的bodyParser,可以按如下方式覆盖它:

require('express').bodyParser.parse['multipart/form-data'] = function yourHandler(req, options, next)...
Run Code Online (Sandbox Code Playgroud)