Matej
Matej

Reputation: 186

JavaScript Using FormData and jQuery's ajax for uploading files returns error 500 when no file is selected on iOS

I'm using FormData and jQuery's ajax for uploading files in form. Everything works fine except when there's no file selected on iOS, then I get error 500 from PHP script.

On PC and Android it works fine if file is or isn't selected, but on iOS it works only if file is selected (it is not required to select file). I am using latest iOS 11.4.1.

This is my code that's called when the form is submitted:

var form = this;
var data = new FormData(form);

var options = {
    url: $(form).attr('action'),
    data: data,
    type: $(form).attr('method'),
    cache: false,
    contentType: false,
    processData: false,
    complete: function(r){
        if(r.status == 200){
            var response = r.responseJSON;

            showErrors(form, response.errors);
            $.each(response.actions, handleAction.bind(form));
        }else{
            showErrors(form, ['Vyskytla sa neočkávaná chyba, skúste znova neskôr']);
        }
    }
};
if(data.fake){
    opts.xhr = function(){
        var xhr = jQuery.ajaxSettings.xhr();
        xhr.send = xhr.sendAsBinary;
        return xhr;
    }
    opts.contentType = 'multipart/form-data;boundary='+data.boundary;
    opts.data = data.toString();
}

$.ajax(options);

There was a part of code that printed the response from server and this was the response:

{"readyState":4,"responseText":"\n\n\n\n
Internal Server Error

\n
The server encountered an internal error or\nmisconfiguration and was unable to complete\nyour request.

\n
Please contact the server administrator at \n [email protected] to inform them of the time this error occurred,\n and the actions you performed just before this error.

\n
More information about this error may be available\nin the server error log.

\n\n","status":500,"statusText":"Internal Server Error"}

Upvotes: 2

Views: 1196

Answers (1)

Matej
Matej

Reputation: 186

I finally found the solution to my problem, it was not on the server side. Looks like FormData puts array of one empty File object on iOS into data variable and server cannot handle that.

I edited JS to this:

var data = new FormData(form);
$.each($(form).find('input[type="file"]'), function(){
    var name = $(this).attr('name');
    var files = $(this).prop('files');

    if(files.length == 0){
        data.set(name, null);
    }
});

Upvotes: 1

Related Questions