На одном из проектов мне потребовалось сделать отправку формы, содержащей файл, посредством ajax. Напрямую эта задача не решается, по этому пришлось делать двойную загрузку: сначала происходит загрузка файла, результат загрузки сообщается скрипту и скрипт движется дальше, отправляя саму форму.
Код формы может быть любой, например такой:
<div ><form action="#" class="vacancy_form"> 
                <input type="text" name="l_name" class="a-name" data-validate="validate(required)"> 
                <input type="text" name="f_name" class="b-name" data-validate="validate(required)"> 
                <input type="file" name="resume" data-validate="validate(required)"> 
                <button class="btn yel_btn">Откликнуться</button> 
                <input type="hidden" name="filename" value=""/> 
</form> Скрипт:
var iframe = $('<iframe id="upload_iframe" name="upload_iframe" style="width:0;height:0;border:0;"></iframe>'); 
        var hidForm = $('<form style="display:none;" target="upload_iframe" enctype="multipart/form-data" action="/ajax/?function=upload_file" method="post" name="upload-form"/>'); 
        $('body').append(iframe).append(hidForm); 
        iframe.load(function(){ 
            var data = $(this).contents().text(); 
            if (data === undefined || data == '') return; 
            iframe.remove(); 
            hidForm.remove(); 
            data = JSON.parse(data); 
            if (data.error == '1') 
            { 
                alert(data.content); 
                return; 
            } 
            form.find('input[name=filename]').val(data.file); 
            $.ajax({ 
                url: '/ajax/?function=vacancy', 
                type: "POST", 
                dataType:"json", 
                data: form.serialize(), 
                success: function(data){ 
                    ... 
                } 
            }); 
        }); 
        var realFile = form.find('input[name=resume]'), 
            realFileVal = realFile.val(), 
            realFile = form.find('input[name=resume]'), 
            newFile = realFile.clone(); 
        realFile.replaceWith(newFile); 
        hidForm.append(realFile).val(realFileVal); 
        hidForm.submit(); Скрипт был почерпнут на просторвх интернета и переделан под свои нужды. Скрипт создает ифрейм и дополнительную форму чтобы не маяться с передачей атрибутов в основную форму. Вспомогательная форма берет из основной инпут файла с его значением, отправляет на сервер строкой hidForm.submit();. После загрузки файла вступает событие iframe.load, в которое сервер передает информацию о загрузке файла и путь до загруженного файла на сервере, Далее полученный путь прописывается в input[name=filename] и происходит передача основной формы через $.ajax. На выходе получаем загруженный файл и переданную форму.