4 回答
TA贡献1862条经验 获得超7个赞
从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']然后将是一个包含上传的每个文件的文件上载字段的数组。我实际上推荐这个在我的初始解决方案,因为它更容易迭代。
TA贡献1993条经验 获得超6个赞
只是想为拉斐尔的回答添加一些内容。$_FILES无论您是否使用JavaScript提交,以下是如何让PHP生成相同的内容。
HTML表单:
<form enctype="multipart/form-data" action="/test.php" method="post" class="putImages"> <input name="media[]" type="file" multiple/> <input class="button" type="submit" alt="Upload" value="Upload" /></form>
PHP $_FILES在没有JavaScript的情况下提交时生成:
Array ( [media] => Array ( [name] => Array ( [0] => Galata_Tower.jpg [1] => 518f.jpg ) [type] => Array ( [0] => image/jpeg [1] => image/jpeg ) [tmp_name] => Array ( [0] => /tmp/phpIQaOYo [1] => /tmp/phpJQaOYo ) [error] => Array ( [0] => 0 [1] => 0 ) [size] => Array ( [0] => 258004 [1] => 127884 ) ) )
如果你进行渐进增强,使用Raphael的JS提交文件......
var data = new FormData($('input[name^="media"]')); jQuery.each($('input[name^="media"]')[0].files, function(i, file) {
data.append(i, file);});$.ajax({
type: ppiFormMethod,
data: data,
url: ppiFormActionURL,
cache: false,
contentType: false,
processData: false,
success: function(data){
alert(data);
}});...这是PHP的$_FILES数组在使用JavaScript提交之后的样子:
Array ( [0] => Array ( [name] => Galata_Tower.jpg [type] => image/jpeg [tmp_name] => /tmp/phpAQaOYo [error] => 0 [size] => 258004 ) [1] => Array ( [name] => 518f.jpg [type] => image/jpeg [tmp_name] => /tmp/phpBQaOYo [error] => 0 [size] => 127884 ) )
这是一个很好的数组,实际上有些人会变换$_FILES,但我发现使用相同的数据是有用的$_FILES,无论JavaScript是否用于提交。所以,这里有一些JS的小改动:
// match anything not a [ or ]regexp = /^[^[\]]+/;var fileInput = $('.putImages input[type="file"]');
var fileInputName = regexp.exec( fileInput.attr('name') );
// make files availablevar data = new FormData();
jQuery.each($(fileInput)[0].files, function(i, file) {
data.append(fileInputName+'['+i+']', file);});(2017年4月14日编辑:我从FormData()的构造函数中删除了表单元素 - 在Safari中修复了此代码。)
那段代码做了两件事。
input自动检索name属性,使HTML更易于维护。现在,只要form有类putImages,其他一切都会自动处理。也就是说,input不需要任何特殊名称。普通HTML提交的数组格式由data.append行中的JavaScript重新创建。注意括号。
通过这些更改,现在使用JavaScript $_FILES提交与使用简单HTML提交的数组完全相同。
TA贡献1757条经验 获得超8个赞
看看我的代码,它为我做的工作
$( '#formId' )
.submit( function( e ) {
$.ajax( {
url: 'FormSubmitUrl',
type: 'POST',
data: new FormData( this ),
processData: false,
contentType: false
} );
e.preventDefault();
} );添加回答
举报
