ExpressJS Multer:将图像上传到服务器

ExpressJS Multer: Upload image to server

我是 Node.js 和 Express.js 的新手。

我想先上传一张图片到服务器(目录:uploads/spots),然后(同步)上传其余的表单数据到MongoDB。

我正在使用 REST(方法 Post)

app.route('/spots').post(users.requiresLogin, spots.create);

我正在使用 Multer 将图像更新到服务器中,并且可以正常工作。

app.use(multer(
        { dest: './public/uploads/spots',
            onFileUploadStart: function (file) {
                var imagePath = file.path;

                gm(imagePath).resize(850, 850).quality(70).noProfile().write('public/uploads/spots/850x850/'+file.name, function (err) {
                    if (!err) {
                        gm(imagePath).resize(150, 150).quality(70).noProfile().write('public/uploads/spots/150x150/'+file.name, function (err) {
                            if (!err) {
                            }
                            else{
                                console.log('Error: '+err);
                            }

                        });
                    }
                    else{
                        console.log('Error: '+err);

                    }

                });

            }

        }));

正在工作,但是是异步的,并且 returns 在将图像上传到服务器之前对前端的响应。

我的问题是如何做到这一点但同步以及如何在上传图像后return对前端的响应。

谢谢!

spots.server.routes.js

'use strict';

module.exports = function(app) {
    var gm = require('gm');
    var multer  = require('multer');


    var users = require('../controllers/users.server.controller.js');
    var spots = require('../controllers/spots.server.controller.js');


    //Upload image
    app.use(multer(
        { dest: './public/uploads/spots',
            onFileUploadStart: function (file) {
                var imagePath = file.path;

                gm(imagePath).resize(850, 850).quality(70).noProfile().write('public/uploads/spots/850x850/'+file.name, function (err) {
                    if (!err) {
                        gm(imagePath).resize(150, 150).quality(70).noProfile().write('public/uploads/spots/150x150/'+file.name, function (err) {
                            if (!err) {
                            }
                            else{
                                console.log('Error: '+err);
                            }

                        });
                    }
                    else{
                        console.log('Error: '+err);

                    }

                });

            }

        }));



 // Spots Routes
 app.route('/spots')
  .get(spots.list)
  .post(users.requiresLogin, spots.create);

 app.route('/spots/:spotId')
  .get(spots.read)
  .put(users.requiresLogin, spots.update)
  .delete(users.requiresLogin, spots.hasAuthorization, spots.delete);

 // Finish by binding the Spot middleware
 app.param('spotId', spots.spotByID);
};

spots.server.controller.js(创建方法)

'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
 errorHandler = require('./errors.server.controller.js'),
 Spot = mongoose.model('Spot'),
 _ = require('lodash'),
    fs = require('fs');



/**
 * Create a Spot
 */
exports.create = function(req, res) {
 var spot = new Spot(JSON.parse(req.body.spot));
 spot.user = req.user;

    if(req.files.file)
        spot.image=req.files.file.name;
    else
        spot.image='default.jpg';


 spot.save(function(err) {
  if (err) {
            fs.unlinkSync('public/uploads/spots/'+spot.image);
            fs.unlinkSync('public/uploads/spots/850x850/'+spot.image);
            fs.unlinkSync('public/uploads/spots/150x150/'+spot.image);
   return res.status(400).send({
    message: errorHandler.getErrorMessage(err)
   });
  } else {
            var socketio = req.app.get('socketio'); // tacke out socket instance from the app container
            socketio.sockets.emit('spot.created.'+spot.municipality,  {spot:spot, user:req.user});
            socketio.sockets.emit('spot.created.'+spot.province,  {spot:spot, user:req.user});
            socketio.sockets.emit('spot.created.'+spot.community,  {spot:spot, user:req.user});
            socketio.sockets.emit('spot.created.'+spot.country,  {spot:spot, user:req.user});

            res.jsonp(spot);
  }
 });


};


/**
 * Spot authorization middleware
 */
exports.hasAuthorization = function(req, res, next) {
 if (req.spot.user.id !== req.user.id) {
  return res.status(403).send('User is not authorized');
 }
 next();
};

解决方案是不使用 onFileUploadStart 方法并在控制器中使用带回调的函数。

路线

  // Spots Routes
    app.route('/spots')
    .get(spots.list)
    .post(users.requiresLogin,multer({ dest: './public/uploads/spots'}), spots.create);

控制器

exports.create = function(req, res) {

if (req.files.file)
    exports.uploadImage(req.files.file,callback);
else
    callback();


    function callback(){
        var spot = new Spot(JSON.parse(req.body.spot));
        spot.user = req.user;

        if (req.files.file)
            spot.image = req.files.file.name;
        else
            spot.image = 'default.jpg';


        spot.save(function (err) {
            if (err) {
                fs.unlink('public/uploads/spots/850x850/'+spot.image);
                fs.unlink('public/uploads/spots/150x150/'+spot.image);
                return res.status(400).send({
                    message: errorHandler.getErrorMessage(err)
                });
            } else {
                var socketio = req.app.get('socketio'); // tacke out socket instance from the app container
                socketio.sockets.emit('spot.created.' + spot.municipality, {spot: spot, user: req.user});
                socketio.sockets.emit('spot.created.' + spot.province, {spot: spot, user: req.user});
                socketio.sockets.emit('spot.created.' + spot.community, {spot: spot, user: req.user});
                socketio.sockets.emit('spot.created.' + spot.country, {spot: spot, user: req.user});


                req.spot = spot;
                Feedback.subscribeSpot(req);

                Notify.getLocalSubscriptors(spot.municipality,spot.province,spot.community,spot.country,function(subscriptions){
                    Notify.create(req,null,spot,null,null,null,subscriptions,'spots/'+spot._id,false,'SPOT_CREATED', function(){
                        res.jsonp(spot);
                    });
                });
            }
        });
    }

};


exports.uploadImage = function(file, fn){
  var imagePath = file.path;

            gm(imagePath).resize(850, 850).quality(70).noProfile().write('public/uploads/spots/850x850/'+file.name, function (err) {
                if (!err) {
                    gm(imagePath).resize(150, 150).quality(70).noProfile().write('public/uploads/spots/150x150/'+file.name, function (err) {
                        if (!err) {
                          if(fn)fn();
                        }
                        else{
                            console.log('Error: '+err);
                        }

                    });
                }
                else{
                    console.log('Error: '+err);

                }

            });

};