简体   繁体   中英

NodeJS & Angular Image upload

Tried lot of available Internet tutorials, but I still can't make it functional. I use multer module in NodeJS and ng-file-upload in AngularJS. I made two helpers with multer settings( because I have two scenarios and both uploads must go to different folders). Backend files are in APP/APP_BACK/ folder, so in destination path I go back one folder and enter APP_FRONT/images/header. Here is one helper snippet (/helpers/uploadHeader.js):

var storage = multer.diskStorage({
destination: function (req, file, callback) {
    callback(null, '../APP_FRONT/images/header/');
},
filename: function (req, file, callback) {  
    var ext = filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2);
    callback(null, file.fieldname + '-' + '.' + ext);
}

});
var upload = multer(
    {storage: storage}
);

var helper = {
    upload: upload
};

module.exports = helper;

Here is router file:

var headerHelper= require('../helpers/uploadHeader');

router.post('/header', headerHelper.upload.single('header'), function(req, res, next) {
   headerHelper.upload(req, res, function(err){
       if(err){
           res.status(400).send(err);
           console.log(err);
           return;
       }
       res.status(200).send({ code:200, message:'Header upload successful!'    });
   });
});

"header" would be name of input form or key value in Postman.

In Angular, I injected 'ngFileUpload' module in app, and injected 'Upload' service into desired controller and used it inside uploadHeader() function which is bound on button inside form on clientside:

$scope.uploadHeader = function (file) {
        Upload.upload({
            url: 'http://localhost:3003/upload/header',
            method: 'POST',
            file: file
        }).then(function (response) {
            console.log('Success ' + response.config.data.file.name + 'uploaded. Response: ' + response.data);
        }, function (error) {
            console.log('Error status: ' + error.status);
        }, function (evt) {
            var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
            console.log('progress: ' + progressPercentage + '% ' + evt.config.data.file.name);
        });

I tried with Postman:

Postman request SS

And get this error:

"Error: ENOENT: no such file or directory, open 'c:\\Users\\Username\\Desktop\\APP\\APP_FRONT\\images\\header\\header.jpg'"

When I try from clientside, I get these errors:

" Error: Unexpected field
at makeError " and " TypeError: dbg is undefined "

I already consulted Google, tried some of tutorials but got stuck on this.

In your router, you are telling multer to look for an object called "header" in the mulitpart form data. Your angularJS code is adding it as an object called 'file'.

If you change the line in your router from:

router.post('/header', headerHelper.upload.single(**'header'**), function(req, res, next) {
//.....
    }

to:

router.post('/header', headerHelper.upload.single(**'file'**), function(req, res, next) {
//....
}

It should do the trick.

EDIT: solution found

Actually, it was problem in filename function in multer's storate settings. In above post, I appended datetimestamp and file extension to fieldname:

filename: function (req, file, callback) {
    var datetimestamp = moment().format('DD-MM-YY_HH:mm:ss');
    var filename = file.originalname;
    var ext = filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2);

    callback(null, file.fieldname + '-' + datetimestamp + '.' + ext);
}

For some reason, it couldn't finish upload and I got error.

I changed filename function to return only file's originalname :

filename: function (req, file, callback) {
        callback(null, file.originalname);
    }

and now everything is OK. But now, question is, why custom filename doesn't work?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM