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条经验 获得超5个赞
只是想为拉斐尔的回答添加一些内容。$_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(); } );
添加回答
举报