ExpressJS Multer: Upload image to server

我怕爱的太早我们不能终老 提交于 2020-01-04 19:47:23

问题


I'm newer with Node.js and Express.js.

I want to upload first a image into the server (directory: uploads/spots), and then (synchronous) upload the rest of form data in MongoDB.

I'm using REST (Method Post)

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

and I'm using Multer for updating the image into the server, and works.

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);

                    }

                });

            }

        }));

Is working, but is asynchronous , and returns the response to frontend before that the image will be upload into the server.

My question is how to do this but synchronous and how to return the response to the frontend after that the image was uploaded.

Thank you!

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 (create method)

'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();
};

回答1:


The solution is not use onFileUploadStart method and use a function with callback in the controller.

routes

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

controller

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);

                }

            });

};


来源:https://stackoverflow.com/questions/28797965/expressjs-multer-upload-image-to-server

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!