3

I'm looking to use Multer to upload an image file onto my node server. The code is simple, I copied it from Multer's docs. I spent the whole day stackoverflowing this issue and it always comes back to giving me undefined for using ajax to send the image.

Using a form DOES work: multer - req.file always undefined

However, I'm curious to see if anyone have successfully used ajax way to sending files.

HTML

<input type="file" id="avatar" name="avatar"/>

When the user clicks on the button and chooses a file, I simply display the file info, and use ajax to send the data to my node router http://localhost:8882/profile

js

<script>
//files structure contains data about each file you load in
   document.getElementById('avatar').addEventListener('change', function() {

    var file = this.files[0];
    console.dir(this.files[0]);

    postItem(this.files[0]);

}, false);


function postItem(imageObj) {
  console.log("postItem <----");
    $.ajax({
        type: "POST",
        url: "http://localhost:8882/profile",
        contentType:false,
        cache: false,
        processData: false,
        data:  imageObj,
        success: function(data) {
            //show content
            alert('Success!');
        },
        error: function(jqXHR, textStatus, err) {
            //show error message
            alert('text status ' + textStatus + ', err: '+err);
        }

    }); //ajax
}//postItem()

</script>

On the Node side, the code is directly from multer's docs: https://www.npmjs.com/package/multer

I keep getting undefined for req.file.

Node

var express     = require('express');
var app         = express();
var bodyParser  = require('body-parser');
var multer  = require('multer')
var upload = multer({ dest: 'uploads/' })

app.post('/profile', upload.single('avatar'), function (req, res, next) {
    console.log("------ /profile --------");

    if(req) {
        console.dir(req.file);
    }

    console.log("------------------------");
    res.send({"message":"ok"});
});

app.listen(8882);
console.log("index.js - listening on port " + 8882);
exports.app = app;

Would appreciate any help.

Community
  • 1
  • 1
rtsao
  • 199
  • 1
  • 14

2 Answers2

3

You can submit the entire form along with the image using FormDatavia ajax.

Script it uses jQuery:

$(function(){
   $('form').submit(function(e){

      //formData sets: multipart/form-data
      var formData = new FormData($(this)[0]);
      $.ajax({
          type:'POST',
          url:'http://localhost:3000/uploads',
          data : formData,                  
          contentType: false,
          processData: false
      }).done(function(data){
          //print response on success
          console.log(data);

      }).fail(function(data) {
            console.log('Error');
        });
      e.preventDefault(); 
    });
})();   

HTML form Sample Code:

<form>            
    <label for="userName">Name</label>
    <input type="text" name="userName"/>
    <br>
    <label for="phoneNumber">PhoneNumber</label>
    <input type="text" name="phoneNumber"/>
    <br>
    <label for="file">UploadFile</label>
    <input type="file" name="avatar"/>
    <input type="submit"/>
</form>

Node.Js Sample Code, you can set the filename for easy access:

//file upload module
const storage = multer.diskStorage({
    destination :function(req,file,cb){
        cb(null,'./uploads');
    },
    filename : function(req,file,cb){
        cb(null,req.file.originalname+'.jpg');
    } 
});

var upload = multer({storage:storage}).single('avatar');

app.post('/uploads',upload,(req,res)=>{

    res.json({
     "fileName":req.file.originalname,
     "userName":req.body.userName,
     "phoneNumer":req.body.phoneNumber     
    });
});
Nivesh
  • 2,573
  • 1
  • 20
  • 28
  • After working through the example, there were some minor adjustments in filename: function(req, file, cb) that I made to get the code working. thanks – rtsao Mar 25 '16 at 07:18
  • well filename is upto you, what u want to keep and how unique you want it. Rest, good to know it worked out. – Nivesh Mar 25 '16 at 12:14
2

There is nothing wrong with your node.js code is giving undefined becuase multer attaches file object to req object. multer middleware parses only 'multipart/format-data', if data is any other format multer passes the request without adding file object and therefore req.file is undefined. So for your code to work you need to send the file in 'multipart/format-data'. this link will be helpful in sending correct ajax request Sending multipart/formdata with jQuery.ajax

hope it helps :)

Community
  • 1
  • 1
FastTurtle
  • 1,747
  • 11
  • 15