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

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

问题描述

我在使用 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屋!

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