小编典典

使用 jQuery.ajax 发送 multipart/formdata

all

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

我知道这是可能的(尽管直到现在我还没有找到任何 jQuery
解决方案,只有原型代码(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);
    }
});

阅读 416

收藏
2022-03-06

共1个答案

小编典典

从 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']然后将是一个数组,其中包含每个上传文件的文件上传字段。实际上,我在最初的解决方案中推荐这个,因为它更容易迭代。

2022-03-06