从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']将是一个包含每个上传文件的文件上传字段的数组。实际上,我建议在初始解决方案中使用这种方法,因为迭代更简单。