На самом деле это не такая тривиальная задача, как может показаться на первый взгляд.
Вот код, который должен осуществлять отправку данных на сервер (не тестировал, могут быть даже синтаксические ошибки):
//У формы должен быть класс "async"
$('form.async').submit(function(e){
e.preventDefault();
var $form=$(this),
$submit=$('['type="submit"]');
if($submit.attr('disabled')!==undefined)
return;
$submit.attr('disabled',true);
new Promise(function(resolve,reject){
var $files=$form.find('[type="file"]'),
files=[],
list=$files.toArray().reduce(function(arr,item){
for(var i=0;i<item.files.length;i++)
arr.push(item.files[i]);
return arr;
},[]),
counter=0,
readEnd=function(){
if(++counter>=list.length)
resolve(files);
};
if(!$files.length)
return resolve(files);
$.each(list,function(file){
(function(file){
var fReader=new FileReader();
fReader.onerror=function(e){
readEnd();
alert('Не удалось прочитать файл');
};
fReader.onload=function(e){
readEnd();
files.push({
name:file.name,
code:this.result
});
};
fReader.readAsDataURL(file);
})(file)
});
}).then(function(files){
var data=$form.serialize();
if(files.length)
data+'&'+files.map(function(item,i){
return 'file['+i+'][name]='+encodeURIComponent(item.name)
+'&file['+i+'][code]='+item.code;
});
$.post($form.attr('action'),data,function(res){
//Handle answer
});
},function(){
alert('Произошла ошибка');
});
});