使用jQuery.ajax发送multipart / formdata

使用jQuery.ajax发送multipart / formdata

我使用jQuery的ajax函数将文件发送到服务器端PHP脚本时遇到问题。可以获取文件列表$('#fileinput').attr('files')但是如何将此数据发送到服务器?使用文件输入时$_POST,服务器端php脚本上的结果array()为0(NULL)。

我知道这是可能的(虽然我到目前为止还没有找到任何jQuery解决方案,只有Prototye代码(http://webreflection.blogspot.com/2009/03/safari-4-multiple-upload-with-progress.html) )。

这似乎是相对较新的,所以请不要通过XHR / Ajax提及文件上传,因为它肯定有用。

我需要Safari 5中的功能,FF和Chrome会很好但不是必需的。

我现在的代码是:

$.ajax({
    url: 'php/upload.php',
    data: $('#file').attr('files'),
    cache: false,
    contentType: 'multipart/form-data',
    processData: false,
    type: 'POST',
    success: function(data){
        alert(data);
    }});


拉风的咖菲猫
浏览 4363回答 4
4回答

牧羊人nacy

从Safari 5 / Firefox 4开始,最简单的方法是使用FormData该类:var&nbsp;data&nbsp;=&nbsp;new&nbsp;FormData();jQuery.each(jQuery('#file')[0].files,&nbsp;function(i,&nbsp;file)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;data.append('file-'+i,&nbsp;file);});所以现在你有了一个FormData对象,随时可以与XMLHttpRequest一起发送。jQuery.ajax({ &nbsp;&nbsp;&nbsp;&nbsp;url:&nbsp;'php/upload.php', &nbsp;&nbsp;&nbsp;&nbsp;data:&nbsp;data, &nbsp;&nbsp;&nbsp;&nbsp;cache:&nbsp;false, &nbsp;&nbsp;&nbsp;&nbsp;contentType:&nbsp;false, &nbsp;&nbsp;&nbsp;&nbsp;processData:&nbsp;false, &nbsp;&nbsp;&nbsp;&nbsp;method:&nbsp;'POST', &nbsp;&nbsp;&nbsp;&nbsp;type:&nbsp;'POST',&nbsp;//&nbsp;For&nbsp;jQuery&nbsp;<&nbsp;1.9 &nbsp;&nbsp;&nbsp;&nbsp;success:&nbsp;function(data){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(data); &nbsp;&nbsp;&nbsp;&nbsp;}});您必须将contentType选项设置为false,强制jQuery不Content-Type为您添加标题,否则,边界字符串将丢失。此外,您必须将processData标志设置为false,否则,jQuery将尝试将您FormData转换为字符串,这将失败。您现在可以使用以下方法在PHP中检索文件:$_FILES['file-0'](只有一个文件,file-0除非您multiple在文件输入中指定了属性,在这种情况下,数字将随每个文件递增。)为旧版浏览器使用FormData仿真var&nbsp;opts&nbsp;=&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;url:&nbsp;'php/upload.php', &nbsp;&nbsp;&nbsp;&nbsp;data:&nbsp;data, &nbsp;&nbsp;&nbsp;&nbsp;cache:&nbsp;false, &nbsp;&nbsp;&nbsp;&nbsp;contentType:&nbsp;false, &nbsp;&nbsp;&nbsp;&nbsp;processData:&nbsp;false, &nbsp;&nbsp;&nbsp;&nbsp;method:&nbsp;'POST', &nbsp;&nbsp;&nbsp;&nbsp;type:&nbsp;'POST',&nbsp;//&nbsp;For&nbsp;jQuery&nbsp;<&nbsp;1.9 &nbsp;&nbsp;&nbsp;&nbsp;success:&nbsp;function(data){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(data); &nbsp;&nbsp;&nbsp;&nbsp;}};if(data.fake)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Make&nbsp;sure&nbsp;no&nbsp;text&nbsp;encoding&nbsp;stuff&nbsp;is&nbsp;done&nbsp;by&nbsp;xhr &nbsp;&nbsp;&nbsp;&nbsp;opts.xhr&nbsp;=&nbsp;function()&nbsp;{&nbsp;var&nbsp;xhr&nbsp;=&nbsp;jQuery.ajaxSettings.xhr();&nbsp;xhr.send&nbsp;=&nbsp;xhr.sendAsBinary;&nbsp;return&nbsp;xhr;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;opts.contentType&nbsp;=&nbsp;"multipart/form-data;&nbsp;boundary="+data.boundary; &nbsp;&nbsp;&nbsp;&nbsp;opts.data&nbsp;=&nbsp;data.toString();}jQuery.ajax(opts);从现有表单创建FormData而不是手动迭代文件,也可以使用现有表单对象的内容创建FormData对象:var&nbsp;data&nbsp;=&nbsp;new&nbsp;FormData(jQuery('form')[0]);使用PHP本机数组而不是计数器只需将文件元素命名为相同,并在括号中结束名称:jQuery.each(jQuery('#file')[0].files,&nbsp;function(i,&nbsp;file)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;data.append('file[]',&nbsp;file);});$_FILES['file']然后将是一个包含上传的每个文件的文件上载字段的数组。我实际上推荐这个在我的初始解决方案,因为它更容易迭代。

ibeautiful

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

陪伴而非守候

看看我的代码,它为我做的工作$(&nbsp;'#formId'&nbsp;) &nbsp;&nbsp;.submit(&nbsp;function(&nbsp;e&nbsp;)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;$.ajax(&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;url:&nbsp;'FormSubmitUrl', &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type:&nbsp;'POST', &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data:&nbsp;new&nbsp;FormData(&nbsp;this&nbsp;), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;processData:&nbsp;false, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contentType:&nbsp;false &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;); &nbsp;&nbsp;&nbsp;&nbsp;e.preventDefault(); &nbsp;&nbsp;}&nbsp;);
打开App,查看更多内容
随时随地看视频慕课网APP