用jQuery.ajax发送multipart / formdata [英] Sending multipart/formdata with jQuery.ajax

查看:199
本文介绍了用jQuery.ajax发送multipart / formdata的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用jQuery的ajax函数将文件发送到服务器端PHP脚本时遇到了问题。
可以用 $('#fileinput').attr('files')来获取文件列表,但是怎么能把这个数据发送到服务器?使用文件输入时,服务器端php脚本的结果数组( $ _ POST )为0( NULL



我知道这是可能的(尽管直到现在我还没有找到任何jQuery解决方案,只有Prototye代码( http://webreflection.blogspot.com/2009/03/safari-4-multiple-upload-with-progress.html ))。
$ b 这似乎是比较新的,所以请不要提及文件上传是不可能通过XHR / Ajax的,因为它确实在工作。 p>

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

  $。ajax({
url:'php / upload.php',
data:$('#file')。attr('files'),
cache:false,
contentType:'multipart / form-data',
processData:false,
类型:'POST',
成功:好玩(数据){
alert(data);
}
});


解决方案

从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,
方法:'POST',
类型: 'POST',//对于jQuery< 1.9
success:function(data){
alert(data);
}
});

必须设置 contentType 选项to false ,迫使jQuery不要为你添加一个 Content-Type 头部,否则边界字符串将会丢失从中。
此外,你必须保持 processData 标志设置为false,否则,jQuery将尝试转换你的 FormData

你现在可以用PHP检索文件了:

  $ _ FILES ['file-0'] 

一个文件 file-0 ,除非您在文件输入中指定了多个属性,在这种情况下,数字)

使用对旧版浏览器进行FormData模拟

  var opts = {
url:' php / upload.php',
data:data,
cache:false,
contentType:false,
processData:false,
方法:'POST',
类型:'POST',//对于jQuery< 1.9
成功:function(data){
alert(data);
}
};
if(data.fake){
//确定没有文本编码的东西是由xhr
opts.xhr = function(){var xhr = jQuery.ajaxSettings.xhr(); xhr.send = xhr.sendAsBinary;返回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。 (jQuery('#file')[0] .files,function(i,file){
data.append('file []',file);
});

$ _ FILES ['file'] will然后是包含上传的每个文件的文件上传字段的数组。我实际上推荐使用我最初的解决方案,因为迭代更简单。


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.

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)).

This seems to be relatively new, so please do not mention file upload would be impossible via XHR/Ajax, because it's definitely working.

I need the functionality in Safari 5, FF and Chrome would be nice but are not essential.

My code for now is:

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

解决方案

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);
});

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);
    }
});

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.

You may now retrieve the file in PHP using:

$_FILES['file-0']

(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.)

Using the FormData emulation for older browsers

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);

Create FormData from an existing form

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]);

Use a PHP native array instead of a counter

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'] 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆