使用 jQuery.ajax 发送 multipart/formdata [英] Sending multipart/formdata with jQuery.ajax
问题描述
我在使用 jQuery 的 ajax 函数将文件发送到服务器端 PHP 脚本时遇到问题.可以使用 $('#fileinput').attr('files')
获取文件列表,但是如何将此数据发送到服务器?使用文件输入时,服务器端 php 脚本上的结果数组 ($_POST
) 为 0 (NULL
).
I've got a problem sending a file to a serverside PHP-script using jQuery's ajax-function.
It's possible to get the File-List with $('#fileinput').attr('files')
but how is it possible to send this Data to the server? The resulting array ($_POST
) on the serverside php-script is 0 (NULL
) when using the file-input.
我知道这是可能的(尽管直到现在我还没有找到任何 jQuery 解决方案,只有 Prototye 代码(http://webreflection.blogspot.com/2009/03/safari-4-multiple-upload-with-progress.html)).
I know it is possible (though I didn't find any jQuery solutions until now, only Prototye code (http://webreflection.blogspot.com/2009/03/safari-4-multiple-upload-with-progress.html)).
这似乎相对较新,所以请不要提及无法通过 XHR/Ajax 上传文件,因为它确实有效.
This seems to be relatively new, so please do not mention file upload would be impossible via XHR/Ajax, because it's definitely working.
我需要 Safari 5、FF 和 Chrome 中的功能会很好但不是必需的.
I need the functionality in Safari 5, FF and Chrome would be nice but are not essential.
我现在的代码是:
$.ajax({
url: 'php/upload.php',
data: $('#file').attr('files'),
cache: false,
contentType: 'multipart/form-data',
processData: false,
type: 'POST',
success: function(data){
alert(data);
}
});
推荐答案
从 Safari 5/Firefox 4 开始,最容易使用 FormData
类:
Starting with Safari 5/Firefox 4, it’s easiest to use the FormData
class:
var data = new FormData();
jQuery.each(jQuery('#file')[0].files, function(i, file) {
data.append('file-'+i, file);
});
所以现在您有一个 FormData
对象,可以与 XMLHttpRequest 一起发送.
So now you have a FormData
object, ready to be sent along with the 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
转换为字符串,这将失败.
It’s imperative that you set the contentType
option to false
, forcing jQuery not to add a Content-Type
header for you, otherwise, the boundary string will be missing from it.
Also, you must leave the processData
flag set to false, otherwise, jQuery will try to convert your FormData
into a string, which will fail.
您现在可以使用 PHP 检索文件:
You may now retrieve the file in PHP using:
$_FILES['file-0']
(只有一个文件,file-0
,除非您在文件输入中指定了 multiple
属性,在这种情况下,数字将随着每个文件递增.)
(There is only one file, file-0
, unless you specified the multiple
attribute on your file input, in which case, the numbers will increment with each file.)
对旧浏览器使用 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 对象:
Instead of manually iterating the files, the FormData object can also be created with the contents of an existing form object:
var data = new FormData(jQuery('form')[0]);
使用 PHP 原生数组代替计数器
只需为您的文件元素命名相同的名称并在括号中结束名称:
Just name your file elements the same and end the name in brackets:
jQuery.each(jQuery('#file')[0].files, function(i, file) {
data.append('file[]', file);
});
$_FILES['file']
然后将是一个包含每个上传文件的文件上传字段的数组.我实际上比我的初始解决方案更推荐这个,因为它更容易迭代.
$_FILES['file']
will then be an array containing the file upload fields for every file uploaded. I actually recommend this over my initial solution as it’s simpler to iterate over.
这篇关于使用 jQuery.ajax 发送 multipart/formdata的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!