 Понадобилось сделать достаточно очевидную, казалось бы, вещь - страничку, на которой можно заполнить несколько полей формы, выбрать несколько файлов и при нажатии на кнопку чтобы всё это вместе отправлялось на сервер без перезагрузки страницы (через ajax).
Понадобилось сделать достаточно очевидную, казалось бы, вещь - страничку, на которой можно заполнить несколько полей формы, выбрать несколько файлов и при нажатии на кнопку чтобы всё это вместе отправлялось на сервер без перезагрузки страницы (через ajax).
Оказалось, что есть ряд ньюансов. По отдельности нет проблем, а чтобы всё вместе - начинаются сложности. В итоге всё заработало, так что предлагаю простой пример. После успешной загрузки сервер возвращает содержимое массивов _POST и _FILES, которое выводится на ту же страницу.
Проверял в Windows версиях FF, Chrome, IE, Opera, а также в Android Chrome и старом Android Browser. Под IOS не проверял - нет под рукой.
Не работает в Safari 5.34/Win. Причина непонятна (симптомы - отправляет файлы нулевой длины).
Не будет работать в IE <9.
Код клиента (javascript):
<!DOCTYPE html>
<html>
<head>
<title>Ajax file and form data upload test by Frog</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
$('#cform').bind('submit', function(event)
{
    event.preventDefault();
    console.log('SUBMIT!');
    var formData = new FormData();
    $.each($("#cform_file")[0].files, function(i, file)
    {
        formData.append('file-'+i, file);
    });
    formData.append('name',$("#cform_name").val());
    formData.append('email',$("#cform_email").val());
    $.ajax({
            url: 'aftest.php',
            type: 'POST',
            contentType: false,
            processData: false,
            cache: false,
            headers: { 'cache-control': 'no-cache' }, // fix for IOS6 (not tested)
            dataType: 'json',
            data: formData,
            timeout: 7000,
            beforeSend: function(x)
            {
                console.log('beforeSend');
            },//beforeSend
            success: function( data )
            {
                console.log('success',data);
                if (data != null)
                {
                   $('#result').prepend(data._FILES);
                   $('#result').prepend(data._POST);
                }//if
                else
                {
                    console.log('success, but no data');
                }//else
            },//success
            error: function( data )
            {
               console.log('error');
            },//error
            complete: function( data )
            {
                console.log('complete');
            }//complete
    });//ajax()
})//submit()
});//.ready
</script>
</head>
<body>
<form id="cform" action="index.php" method="POST" enctype = "multipart/form-data">
Name: <input id="cform_name" name="cform_name" type="text" size="30" maxlength="30" /><br/>
E-Mail: <input id="cform_email" name="cform_email" type="text" size="30" maxlength="30" /><br/>
<input type="hidden" value="2000000" name="MAX_FILE_SIZE">
<input id="cform_file" type="file" size="20" name="cform_file[]" multiple=""><br/>
<!--
for single file upload replace with:
<input id="cform_file" type="file" size="20" name="cform_file">
-->
<br/>
<input id="cform_submit" name="cform_submit" type="submit" value="SEND" ><br/>
</form>
<hr>
<div id="result"></div>
</body>
</html>
Код сервера (php):
 foreach($_FILES as $file) 
echo json_encode(  Array("_POST"=>'_POST ' . nl2br(print_r($_POST,true)), "_FILES"=>'_FILES ' . nl2br(print_r($_FILES,true)))  );
{
    move_uploaded_file($file["tmp_name"], $file["name"]);
}//foreach
 "Finally, we come to the instruction we've all been waiting for – SEX!"  / из статьи про микропроцессор CDP1802 /          В начале 1970-х в США были весьма популярны простые электронные игры типа Pong (в СССР их аналоги появились в продаже через 5-10 лет). Как правило, такие игры не имели микропроцессора и памяти в современном понимании этих слов, а строились на жёсткой  ...далее
"Finally, we come to the instruction we've all been waiting for – SEX!"  / из статьи про микропроцессор CDP1802 /          В начале 1970-х в США были весьма популярны простые электронные игры типа Pong (в СССР их аналоги появились в продаже через 5-10 лет). Как правило, такие игры не имели микропроцессора и памяти в современном понимании этих слов, а строились на жёсткой  ...далее