0

I'm trying to upload a binary file to a server, but avoid a complete page refresh when the server responds. I'm far from experienced at this type of thing so everything about the way I'm doing it is subject to correction.

This is what I have done.

I have HTML like this:

<form id='form'>
    <input type='file' id='filename'></input>
    <input type='submit' onclick='doTheBusiness'></input>
</form>

I have javascript like this:

function doTheBusiness () {
    var url = '/target.html?arg1=' + val1 + '&arg2=' + val2;
    var fd = new FormData ($('#filename')[0]);
    $.each (
        $.ajax ({
             'url':         url,
             'type':        'post',
             'processData': false,
             'contentType': 'multipart/form-data',
             'success':     success-routine,
             'data':        {
                 'formData': fd
             }
        });
}

Before I added 'processData': false, I was getting an exception from Firefox and Chrome that appeared to be caused because the ajax function was trying to serialise my FormData object. When I looked into resolving that, I found that if I didn't have 'contentType': 'multipart/form-data' it would default to application/x-www-form-urlencoded and I didn't think that would be any use for the file contents. Once I'd done all that, I found that I couldn't access my arg1 and arg2 parameters on the server if I put them into the 'data' object as I have done in other places, so I hand-encoded them into the URL.

Unfortunately it's not working. Using Firefox, I now don't see the request at the server. Chrome and IE11 send a request, but I get an Internal apreq error when I call apreq_body to see if I can get to the uploaded file data. I've been through the mod_apreq code, and found that Internal apreq error corresponds to APREQ_ERROR_GENERAL, but that error seems to be just what it says, a general error code and I didn't like the idea of trying to follow all the possible places where it might be generated.

(I've already seen How to send FormData objects with Ajax-requests in jQuery? which pointed me towards the 'processData' and 'contentType' properties.)

I speculate that I am constructing the request wrongly, and it's so wrong that Firefox is (silently) refusing to send it. Chrome and IE11 are sending the request, but it's then not possible for Apache to parse it. (It might be that this is what caused my problems trying to access the parameters and I can move them back to the 'data' object once I manage to send the file contents correctly.)

Please help me to correct this code and allow me to upload binary files without any more external scripts apart from vanilla jQuery; I suspect that even upgrading to a version later than jquery.1.7.2.min.js would be a step too far for my employers.

Community
  • 1
  • 1
nurdglaw
  • 2,107
  • 19
  • 37

1 Answers1

0
  • processData and contentType needs to be false
  • The FormData constructor takes a form as a parameter not a file input.

    var fd = new FormData ($('#form')[0]);
    
  • Pass the form data object as the data parameter.

    'data': fd,
    
Musa
  • 96,336
  • 17
  • 118
  • 137
  • Thank you very much. Of the three problems in the code I posted, the constructor argument to FormData was a transcription error, as you might expect my real code is a little more complex! I might have found the problem with the data member on my own - I mustn't wrap it in another object. I don't think I would ever have found the contentType problem as I misread the documentation [on the jQuery site](http://api.jquery.com/jQuery.ajax/). – nurdglaw Jan 16 '15 at 17:00