为了账号安全,请及时绑定邮箱和手机立即绑定

使用jQuery.ajax发送multipart / formdata

使用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);     }});
查看完整描述

4 回答

?
牧羊人nacy

TA贡献1862条经验 获得超7个赞

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


查看完整回答
反对 回复 2019-05-24
?
ibeautiful

TA贡献1993条经验 获得超5个赞

只是想为拉斐尔的回答添加一些内容。$_FILES无论您是否使用JavaScript提交,以下是如何让PHP生成相同的内容。

HTML表单:

<form enctype="multipart/form-data" action="/test.php" method="post" class="putImages">
   <input name="media[]" type="file" multiple/>
   <input class="button" type="submit" alt="Upload" value="Upload" /></form>

PHP $_FILES在没有JavaScript的情况下提交时生成:

Array
(
    [media] => Array
        (
            [name] => Array
                (
                    [0] => Galata_Tower.jpg
                    [1] => 518f.jpg
                )

            [type] => Array
                (
                    [0] => image/jpeg
                    [1] => image/jpeg
                )

            [tmp_name] => Array
                (
                    [0] => /tmp/phpIQaOYo
                    [1] => /tmp/phpJQaOYo
                )

            [error] => Array
                (
                    [0] => 0
                    [1] => 0
                )

            [size] => Array
                (
                    [0] => 258004
                    [1] => 127884
                )

        )

)

如果你进行渐进增强,使用Raphael的JS提交文件......

var data = new FormData($('input[name^="media"]'));     jQuery.each($('input[name^="media"]')[0].files, function(i, file) {
    data.append(i, file);});$.ajax({
    type: ppiFormMethod,
    data: data,
    url: ppiFormActionURL,
    cache: false,
    contentType: false,
    processData: false,
    success: function(data){
        alert(data);
    }});

...这是PHP的$_FILES数组在使用JavaScript提交之后的样子:

Array
(
    [0] => Array
        (
            [name] => Galata_Tower.jpg
            [type] => image/jpeg
            [tmp_name] => /tmp/phpAQaOYo
            [error] => 0
            [size] => 258004
        )

    [1] => Array
        (
            [name] => 518f.jpg
            [type] => image/jpeg
            [tmp_name] => /tmp/phpBQaOYo
            [error] => 0
            [size] => 127884
        )

)

这是一个很好的数组,实际上有些人会变换$_FILES,但我发现使用相同的数据是有用的$_FILES,无论JavaScript是否用于提交。所以,这里有一些JS的小改动:

// match anything not a [ or ]regexp = /^[^[\]]+/;var fileInput = $('.putImages input[type="file"]');
var fileInputName = regexp.exec( fileInput.attr('name') );
// make files availablevar data = new FormData();
jQuery.each($(fileInput)[0].files, function(i, file) {
    data.append(fileInputName+'['+i+']', file);});

(2017年4月14日编辑:我从FormData()的构造函数中删除了表单元素 - 在Safari中修复了此代码。)

那段代码做了两件事。

  1. input自动检索name属性,使HTML更易于维护。现在,只要form有类putImages,其他一切都会自动处理。也就是说,input不需要任何特殊名称。

  2. 普通HTML提交的数组格式由data.append行中的JavaScript重新创建。注意括号。

通过这些更改,现在使用JavaScript $_FILES提交与使用简单HTML提交的数组完全相同。


查看完整回答
反对 回复 2019-05-24
?
陪伴而非守候

TA贡献1757条经验 获得超8个赞

看看我的代码,它为我做的工作

$( '#formId' )
  .submit( function( e ) {
    $.ajax( {
      url: 'FormSubmitUrl',
      type: 'POST',
      data: new FormData( this ),
      processData: false,
      contentType: false
    } );
    e.preventDefault();
  } );


查看完整回答
反对 回复 2019-05-24
  • 4 回答
  • 0 关注
  • 4362 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信