jquery - 使用 jQuery.ajax 发送 multipart/formdata

标签 jquery ajax file-upload multipartform-data form-data

我在使用 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 ))。

这似乎是相对较新的,所以请不要提及通过 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);
    }
});

最佳答案

从 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 header ,否则,边界字符串将会丢失。 另外,您必须将 processData 标志设置为 false,否则,jQuery 将尝试将您的 FormData 转换为字符串,这将失败。

您现在可以使用 PHP 检索文件:

$_FILES['file-0']

(只有一个文件,file-0,除非您在文件输入上指定了multiple 属性,在这种情况下,数字将随着每个文件而递增.)

使用FormData emulation对于旧版浏览器

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

关于jquery - 使用 jQuery.ajax 发送 multipart/formdata,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54000221/

相关文章:

javascript - 如何将数据传递给输入值

php - ajax 和 seo 加载单页的最佳实践

php - 请求readystate总是返回0?

java - 如何在android中将音频从sd卡上传到服务器

javascript - 无法提醒 jquery slider 值

javascript - 在打开状态下加载 jQuery UI 自动完成中更改的数据

php - reCAPTCHA PHP 和 AJAX

javascript - Ajax请求仅返回错误但状态码为200 OK

java - 使用文件输入流时找不到文件异常

javascript - 如何在图标单击时激活拖放区