在Express Route中使用Multer?(使用MEANJS)

aik*_*rei 13 javascript express meanjs multer

我正在使用Multer在Express 4中上传图像.但是,这些示例都显示Multer在Express文件中被定义为Middleware.我想在我的应用程序路由本身中实际定义一些Multer行为.这可能吗?我需要的最终结果是我的路由功能在将服务器响应发送到浏览器之前识别上传完成的时间,因此可以向用户显示图像(现在我只显示部分图像,因为该文件尚未完成上传).

当前的工作代码

express.js

// Require Multer as module dependency.
var multer = require('multer');

// Using Multer for file uploads.
app.use(multer({
    dest: './public/profile/img/',
    limits: {
        fieldNameSize: 50,
        files: 1,
        fields: 5,
        fileSize: 1024 * 1024
    },
    rename: function(fieldname, filename) {
        return filename;
    },
    onFileUploadStart: function(file) {
        if(file.mimetype !== 'image/jpg' && file.mimetype !== 'image/jpeg' && file.mimetype !== 'image/png') {
            return false;
        }
    }
}));
Run Code Online (Sandbox Code Playgroud)

server_routes.js

app.route('/users/image').post(server_controller_file.imageUpload);
Run Code Online (Sandbox Code Playgroud)

server_controller_file.js

exports.imageUpload = function(req, res) {
// Check to make sure req.files contains a file, mimetypes match, etc., then send appropriate server response.
};
Run Code Online (Sandbox Code Playgroud)

理想情况下,我的server_controller_file.js将包含一些检查以确保文件完成上传,例如(注意:这是假设的/可取的,而不是实际的工作代码)...

var multer = require('multer');
exports.imageUpload = function(req, res) {
    multer({
        onFileUploadComplete: function(file) {
            res.send();
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

同样,现在节点的异步性质导致浏览器在收到成功响应后认为上传已完成,因此当我更新URL以显示图像时,它仅部分显示.谢谢您的帮助!

小智 17

实际上你可以用另一种方法做你想做的事:

var express = require('express');
var multer  = require('multer');
var upload = multer({ dest: './uploads/'});
var app = express();

app.get('/', function(req, res){
  res.send('hello world');
});

// accept one file where the name of the form field is named photho
app.post('/', upload.single('photho'), function(req, res){
    console.log(req.body); // form fields
    console.log(req.file); // form files
    res.status(204).end();
});

app.listen(3000);
Run Code Online (Sandbox Code Playgroud)

  • 与标记为答案的解决方案相比,这是一种更好的方法.它优化了每条路由的中间件.如果将多个中间件链接在一起,您会发现,表达使用流,但这并不完全适用于中间件.事件不是在中间件之间传递的.如果您在链中使用两个快速中间件,并且每个都尝试捕获所有流事件并在完成所有事件后调用next(),则第二个中间件将不再接收所需的事件.在这种情况下,您需要优化每个路由的中间件. (2认同)

aik*_*rei 7

好的,我实际上刚刚写完原始数据.如果设置inMemorytrue,则将原始数据发送到req.files.file.buffer.这是最终的,有效的解决方案:

express.js

// Using Multer for file uploads.
app.use(multer({
    dest: './public/profile/img/',
    limits: {
        fieldNameSize: 50,
        files: 1,
        fields: 5,
        fileSize: 1024 * 1024
    },
    rename: function(fieldname, filename) {
        return filename;
    },
    onFileUploadStart: function(file) {
        console.log('Starting file upload process.');
        if(file.mimetype !== 'image/jpg' && file.mimetype !== 'image/jpeg' && file.mimetype !== 'image/png') {
            return false;
        }
    },
    inMemory: true //This is important. It's what populates the buffer.
}));
Run Code Online (Sandbox Code Playgroud)

server_controller_file.js

exports.imageUpload = function(req, res) {
    var file = req.files.file,
        path = './public/profile/img/';

    // Logic for handling missing file, wrong mimetype, no buffer, etc.

    var buffer = file.buffer, //Note: buffer only populates if you set inMemory: true.
        fileName = file.name;
    var stream = fs.createWriteStream(path + fileName);
    stream.write(buffer);
    stream.on('error', function(err) {
        console.log('Could not write file to memory.');
        res.status(400).send({
            message: 'Problem saving the file. Please try again.'
        });
    });
    stream.on('finish', function() {
        console.log('File saved successfully.');
        var data = {
            message: 'File saved successfully.'
        };
        res.jsonp(data);
    });
    stream.end();
    console.log('Stream ended.');
};
Run Code Online (Sandbox Code Playgroud)