Начиная с Safari 5 / Firefox 4, проще всего использовать класс FormData
:
var data = new FormData();
jQuery.each(jQuery('#file')[0].files, function(i, file) {
data.append('file-'+i, file);
});
Итак, теперь у вас есть объект FormData
, готовый к отправке вместе с XMLHttpRequest.
jQuery.ajax({
url: 'php/upload.php',
data: data,
cache: false,
contentType: false,
processData: false,
method: 'POST',
type: 'POST', // For jQuery < 1.9
success: function(data){
alert(data);
}
});
Обязательно установить параметр contentType
на false
, заставляя jQuery не добавлять к вам заголовок Content-Type
, иначе пограничная строка будет отсутствовать. Кроме того, вы должны оставить флаг processData
установленным как false, в противном случае jQuery попытается преобразовать ваш FormData
в строку, которая потерпит неудачу.
Теперь вы можете получить файл на PHP, используя:
$_FILES['file-0']
(Существует только один файл, file-0
, если вы не указали атрибут multiple
на входе файла, и в этом случае числа будут увеличиваться с каждым файлом.)
Использование эмуляции FormData для старых браузеров
var opts = {
url: 'php/upload.php',
data: data,
cache: false,
contentType: false,
processData: false,
method: 'POST',
type: 'POST', // For jQuery < 1.9
success: function(data){
alert(data);
}
};
if(data.fake) {
// Make sure no text encoding stuff is done by xhr
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();
}
jQuery.ajax(opts);
Создание FormData из существующей формы
Вместо ручного итерации файлов FormData объект также может быть создан с содержимым существующего объекта формы:
var data = new FormData(jQuery('form')[0]);
Использовать собственный массив PHP вместо счетчика
Просто назовите ваши файловые элементы одинаковыми и запустите имя в скобках:
jQuery.each(jQuery('#file')[0].files, function(i, file) {
data.append('file[]', file);
});
$_FILES['file']
будет массивом, содержащим поля для загрузки файлов для каждого загруженного файла. Я действительно рекомендую это по сравнению с моим первоначальным решением, поскольку его проще перебирать.