如何使用Formidable将文件上传直接传输到Mongo的GridFS?

时间:2021-12-26 16:03:32

I am trying to stream an upload from Formidable directly into Mongo's GridFS.

我正在尝试将从Formidable上传的内容直接流式传输到Mongo的GridFS。

The GridStore needs to be opened before any data can be written however in the time it takes to open the store, too much data is already unparsed and it fails.

GridStore需要在可以写入任何数据之前打开,但是在打开存储所需的时间内,过多的数据已经被解析并且失败了。

How can I prepare the GridStore then handle the incoming upload?

如何准备GridStore然后处理传入的上传?

function upload (request, response, next, options) {
    var form = new Formidable.IncomingForm();

    var store = new Mongo.GridStore(options.mongoose.connection.db, new ObjectID, 'w+', {
        root: 'store',
        chunk_size: 1024 * 64
    } );

    form.onPart = function (part) {
        if(!part.filename){
            form.handlePart(part);
            return;
        }

        part.on('data', function(buffer){
            store.write(buffer);
        });

        part.on('end', function() {
            store.close();
        });
    };

    store.open( function (error, store) {
        form.parse(request);
    });

    response.send();
}

Also the store instantiation and open should probably be put inside onPart somehow.

商店实例化和打开也应该以某种方式放在onPart中。

Alex

亚历克斯

2 个解决方案

#1


3  

Since opening a GridStore file is async and formidable is not, you'll need to do some manual buffering of formidables incoming stream while waiting for the GridStore file to open. Since GridFS cannot be piped to you'll then need to manually write each buffered chunk to the GridStore after it opens.

由于打开GridStore文件是异步的并且没有强大的功能,因此您需要在等待GridStore文件打开时对强大的传入流进行一些手动缓冲。由于GridFS无法通过管道传输,因此需要在打开后手动将每个缓冲的块写入GridStore。

Just released gridform which should do what you need.

刚发布的gridform应该可以满足您的需求。

https://github.com/aheckmann/gridform

https://github.com/aheckmann/gridform

#2


1  

You could move your form's handling code into the store.open callback, for example :

您可以将表单的处理代码移动到store.open回调中,例如:

function upload (request, response, next, options) {

    var store = new Mongo.GridStore(options.mongoose.connection.db, new ObjectID, 'w+', {
        root: 'store',
        chunk_size: 1024 * 64
    } );


    store.open( function (error, store) {
        var form = new Formidable.IncomingForm();
        form.onPart = function (part) {
            if(!part.filename){
                form.handlePart(part);
                return;
            }

            part.on('data', function(buffer){
                store.write(buffer);
            });

            part.on('end', function() {
                store.close();
            });
        };
        form.parse(request);
    });

    response.send();
}

#1


3  

Since opening a GridStore file is async and formidable is not, you'll need to do some manual buffering of formidables incoming stream while waiting for the GridStore file to open. Since GridFS cannot be piped to you'll then need to manually write each buffered chunk to the GridStore after it opens.

由于打开GridStore文件是异步的并且没有强大的功能,因此您需要在等待GridStore文件打开时对强大的传入流进行一些手动缓冲。由于GridFS无法通过管道传输,因此需要在打开后手动将每个缓冲的块写入GridStore。

Just released gridform which should do what you need.

刚发布的gridform应该可以满足您的需求。

https://github.com/aheckmann/gridform

https://github.com/aheckmann/gridform

#2


1  

You could move your form's handling code into the store.open callback, for example :

您可以将表单的处理代码移动到store.open回调中,例如:

function upload (request, response, next, options) {

    var store = new Mongo.GridStore(options.mongoose.connection.db, new ObjectID, 'w+', {
        root: 'store',
        chunk_size: 1024 * 64
    } );


    store.open( function (error, store) {
        var form = new Formidable.IncomingForm();
        form.onPart = function (part) {
            if(!part.filename){
                form.handlePart(part);
                return;
            }

            part.on('data', function(buffer){
                store.write(buffer);
            });

            part.on('end', function() {
                store.close();
            });
        };
        form.parse(request);
    });

    response.send();
}