Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Image Upload hanging on mobile browsers but not on local computer - Node JS, Express

We are currently experiencing image uploads that hang when we attempt to use a mobile browser but not when we use the development computer. We think that the express.bodyParser middleware is the culprit as it doesn't get to the code in our server. We are using node 0.10.11 and express 3.2.5

This is the relevant server code

// --- Server Setup --- \\  
var server = express();

// all environments
server.set('port', process.env.PORT || 3000);
server.engine('ejs', engine);
server.set('views', __dirname + '/views');
server.set('view engine', 'ejs');
server.use(express.favicon());
server.use(express.logger('dev'));
server.use(express.json())
server.use(express.urlencoded())
server.use(express.methodOverride());
server.use(express.cookieParser('your secret here'));
server.use(express.session());
//Passport stuff
server.use(passport.initialize());
server.use(passport.session());

server.use(express.static(path.join(__dirname, 'public')));
server.use(server.router);

// development only
if ('development' == server.get('env')) {
  server.use(express.errorHandler());
}

// This is the problem route, mw.validateUID just validates the uid and we know that is working 
// where as it seems to stop working at the express.bodyParser
server.post('/photo/:uid', mw.validateUID, express.bodyParser({'keepExtensions': true}), express.limit('2mb'), app.uploadPhoto);

Relevant Calling Code

RestClient = function() { 
    var xhr = new XMLHttpRequest();

    function init() {
      return {
         postImage: function(path, image, callback) {
           if (image.size > 2500000) {
              callback(-1);
              return;
           }

           var formData = new FormData();               
           formData.append('photo', image);

           xhr.open('POST', path, true);
           xhr.send(formData);
           xhr.onreadystatechange = function() {
             if (this.readyState == this.DONE) {
               callback(this.status);
              } 
           };
         }
       }
}

and

processImage = function(imageFile) {
  if (user.getId()) {
    restClient.postImage('/photo/' + user.getId(), imageFile, function(status) {
      if (status < 0) {
        alert("Your image must be less than 2.5M in size.");
      } else if (status == 200) {
        reset(true);
        if (!successView) {
          successView = SuccessView();
        }
        successView.show();
      } else {
        alert("Sorry, we're unable to upload your photo.  Please try again later.");
      }                 
    });
  } else {
    alert('login to fb!');
  }
}

Edit:

Also this is the error message that we encountered.

Error: Request aborted
    at IncomingMessage.<anonymous> (/home/pinnacle_vodka/node_modules/express/node_modules/connect/node_modules/formidable/lib/incoming_form.js:107:19)
    at IncomingMessage.EventEmitter.emit (events.js:92:17)
    at abortIncoming (http.js:1881:11)
    at Socket.serverSocketCloseListener (http.js:1893:5)  
    at Socket.EventEmitter.emit (events.js:117:20)
    at TCP.close (net.js:466:12)
like image 400
William Ridder Avatar asked Nov 13 '22 03:11

William Ridder


1 Answers

The trouble lies in the middle ware of your express app.

You have used :

server.use(express.bodyParser());

Which tells Express to handle JSON, URLEncoded and multipart requests. However, there seems to be a node Formidable module to handle multipart requests also. The solution is to either use only URLEncoded and handle the upload in formidable, or not use formidable and handle everything in bodyparser.

So your code should now look like:

a)Formidable upload:

server.use(express.urlencoded());
//server.use(express.methodOverride());
//server.use(express.bodyParser());

or b)Express Multipart upload:

//server.use(express.urlencoded());
//server.use(express.methodOverride());
server.use(express.bodyParser());

There is a reference to node_modules/formidable/lib/incoming_form.js:107:19 somewhere in the code, remove it if you use option b.

like image 158
amarprabhu Avatar answered Nov 15 '22 05:11

amarprabhu