Ramsel Ramsel -4 years ago 143
Javascript Question

XHR sending image file and string not working

This seems like it should be so simple but it's taking me hours to figure out.

I want to post an image file along with stringified coordinates so I can crop the image server-side.

Here's my client-side code:

var formdata = new FormData();
formdata.append("file", file);
formdata.append("coords", JSON.stringify(coordInfo));

var xhr = new XMLHttpRequest();
if ( xhr.upload ) {

// for handling the progress of the upload
xhr.upload.addEventListener('progress',progressHandlingFunction, false);
}
xhr.onreadystatechange = function(e) {
if ( 4 == this.readyState ) {
console.log(['xhr upload complete', e]);
}
};
xhr.open('post', '/changeProfilePicture', true);
xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');
xhr.send(formdata);


My relevant Express middleware is:

var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use('/changeProfilePicture', multipartMiddleware);


And in my route I'm just logging out values to see if they were passed:

console.log("req.body.file");
console.log(req.body.file);
console.log("req.body.coords");
console.log(req.body.coords);
console.log("req.body.formdata");
console.log(req.body.formdata);
console.log("req.body");
console.log(req.body);





In Chrome my
request payload
looks like:

------WebKitFormBoundary6A5RYri63wa7LqdB
Content-Disposition: form-data; name="file"; filename="monkey_mad.jpg"
Content-Type: image/jpeg


------WebKitFormBoundary6A5RYri63wa7LqdB
Content-Disposition: form-data; name="coords"

{"x":110.13333333333334,"y":103.841059602649,"x2":560,"y2":550.728476821192,"w":449.8666666666667,"h":446.887417218543}
------WebKitFormBoundary6A5RYri63wa7LqdB--


But server-side the logs only show the
coords
:

17:53:19 web.1 | req.body.file
17:53:19 web.1 | undefined
17:53:19 web.1 | req.body.coords
17:53:19 web.1 | {"x":110.13333333333334,"y":103.841059602649,"x2":560,"y2":550.728476821192,"w":449.8666666666667,"h":446.887417218543}
17:53:19 web.1 | req.body.formdata
17:53:19 web.1 | undefined
17:53:19 web.1 | req.body
17:53:19 web.1 | { coords: '{"x":110.13333333333334,"y":103.841059602649,"x2":560,"y2":550.728476821192,"w":449.8666666666667,"h":446.887417218543}' }


I feel like I've tried every variation there is client-side and server-side to get this to work. Previously I was using an AJAX XHR Request and busboy server-side to parse the request. I would get a file object I could save but when retrieved it would display as a broken image.

Here's that S.O. question which is unresolved.

So now I'm trying a non-AJAX XHR and am using
connect-multiparty
as the parse, but still no luck.

Answer Source

The files should be in req.files instead of req.body.

Also, unrelated, you should note that req.body.coords looks like a string of JSON, not an object. You'll need to JSON.parse it to use it as an object, just in case it was something missed.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download