关于javascript:如何在jquery中使用ajax请求发送formdata对象?

How to send FormData objects with Ajax-requests in jQuery?

本问题已经有最佳答案,请猛点这里访问。

xmlhttpRequestLevel2标准(仍然是工作草案)定义了FormData接口。这个接口允许将File对象附加到xhr请求(ajax请求)中。

顺便说一句,这是一个新功能-在过去,使用了"隐藏的iframe技巧"(在我的另一个问题中阅读)。

这就是它的工作原理(示例):

1
2
3
4
5
6
7
var xhr = new XMLHttpRequest(),
    fd = new FormData();

fd.append( 'file', input.files[0] );
xhr.open( 'POST', 'http://example.com/script.php', true );
xhr.onreadystatechange = handler;
xhr.send( fd );

其中input字段,handler是ajax请求的成功处理程序。

这在所有浏览器中都能很好地工作(同样,除了IE)。

现在,我想让这个功能与jquery一起工作。我试过这个:

1
2
3
4
var fd = new FormData();    
fd.append( 'file', input.files[0] );

$.post( 'http://example.com/script.php', fd, handler );

不幸的是,这是行不通的(一个"非法调用"错误被抛出-屏幕截图在这里)。我假设jQuery需要一个简单的键值对象,它表示表单字段名/值,而我通过的EDCOX1 OR 0实例显然是不兼容的。

现在,由于可以将EDCOX1的0个实例传递到EDCOX1(7)中,所以我希望它也能使它与jQuery一起工作。

更新:

我在jquery的bug追踪器上创建了一个"功能标签"。它在这里:http://bugs.jquery.com/ticket/9995

我被建议使用"Ajax预过滤器"…

更新:

首先,让我演示一下我想要实现什么样的行为。

HTML:

1
2
3
4
<form>
    <input type="file" id="file" name="file">
    <input type="submit">
</form>

JavaScript:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$( 'form' ).submit(function ( e ) {
    var data, xhr;

    data = new FormData();
    data.append( 'file', $( '#file' )[0].files[0] );

    xhr = new XMLHttpRequest();

    xhr.open( 'POST', 'http://hacheck.tel.fer.hr/xml.pl', true );
    xhr.onreadystatechange = function ( response ) {};
    xhr.send( data );

    e.preventDefault();
});

以上代码导致此HTTP请求:

multipartformdata

这就是我需要的-我想要"多部分/表单数据"内容类型!

建议的解决方案如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$( 'form' ).submit(function ( e ) {
    var data;

    data = new FormData();
    data.append( 'file', $( '#file' )[0].files[0] );

    $.ajax({
        url: 'http://hacheck.tel.fer.hr/xml.pl',
        data: data,
        processData: false,
        type: 'POST',
        success: function ( data ) {
            alert( data );
        }
    });

    e.preventDefault();
});

但是,这会导致:

wrongcontenttype

如你所见,内容类型是错误的…


我相信你可以这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
var fd = new FormData();    
fd.append( 'file', input.files[0] );

$.ajax({
  url: 'http://example.com/script.php',
  data: fd,
  processData: false,
  contentType: false,
  type: 'POST',
  success: function(data){
    alert(data);
  }
});

processData设置为false可以防止jquery自动将数据转换为查询字符串。有关详细信息,请参阅文档。

必须将contentType设置为false,否则jquery会将其设置错误。


有一些技术还没有被提到,可供您使用。首先在Ajax参数中设置ContentType属性。

以Pradeek的例子为基础:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
$('form').submit(function (e) {
    var data;

    data = new FormData();
    data.append('file', $('#file')[0].files[0]);

    $.ajax({
        url: 'http://hacheck.tel.fer.hr/xml.pl',
        data: data,
        processData: false,
        type: 'POST',

        // This will override the content type header,
        // regardless of whether content is actually sent.
        // Defaults to 'application/x-www-form-urlencoded'
        contentType: 'multipart/form-data',

        //Before 1.5.1 you had to do this:
        beforeSend: function (x) {
            if (x && x.overrideMimeType) {
                x.overrideMimeType("multipart/form-data");
            }
        },
        // Now you should be able to do this:
        mimeType: 'multipart/form-data',    //Property added in 1.5.1

        success: function (data) {
            alert(data);
        }
    });

    e.preventDefault();
});

在某些情况下,当强制jquery ajax执行非预期的操作时,beforeSend事件是一个很好的地方。有一段时间,人们在1.5.1中把mimetype添加到jquery之前,使用beforeSend覆盖mimetype。您应该能够在发送前事件中修改jqxhr对象上的任何内容。


您可以使用以下代码在Ajax请求中发送FormData对象,

1
2
3
$("form#formElement").submit(function(){
    var formData = new FormData($(this)[0]);
});

这与公认的答案非常相似,但却是问题主题的实际答案。这将在FormData中自动提交表单元素,您不需要手动将数据追加到FormData变量。

Ajax方法如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$("form#formElement").submit(function(){
    var formData = new FormData($(this)[0]);
    //append some non-form data also
    formData.append('other_data',$("#someInputData").val());
    $.ajax({
        type:"POST",
        url: postDataUrl,
        data: formData,
        processData: false,
        contentType: false,
        dataType:"json",
        success: function(data, textStatus, jqXHR) {
           //process data
        },
        error: function(data, textStatus, jqXHR) {
           //process error msg
        },
});

您还可以手动将FormData对象内的表单元素作为这样的参数传递

1
2
var formElem = $("#formId");
var formdata = new FormData(form[0]);

希望它有帮助。;)


我是这样做的,这对我很有用,我希望这能有所帮助。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
        <form>
            <input type="file" name="userfile" id="userfile" size="20" />
            <br /><br />
            <input type="button" id="upload" value="upload" />
        </form>
   
 
        $(document).ready(function(){
                $('#upload').click(function(){

                    console.log('upload button clicked!')
                    var fd = new FormData();    
                    fd.append( 'userfile', $('#userfile')[0].files[0]);

                    $.ajax({
                      url: 'upload/do_upload',
                      data: fd,
                      processData: false,
                      contentType: false,
                      type: 'POST',
                      success: function(data){
                        console.log('upload success!')
                        $('#data').empty();
                        $('#data').append(data);

                      }
                    });
                });
        });


您可以使用$.ajax EDCOX1 2事件来操作报头。

1
2
3
beforeSend: function(xhr) {
    xhr.setRequestHeader('Content-Type', 'multipart/form-data');
}

请参阅此链接以获取其他信息:http://MSDN。微软/Eng/Eng/图书馆/MS53675(V= V.85)。


JavaScript:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function submitForm() {
    var data1 = new FormData($('input[name^="file"]'));
    $.each($('input[name^="file"]')[0].files, function(i, file) {
        data1.append(i, file);
    });

    $.ajax({
        url:"<?php echo base_url() ?>employee/dashboard2/test2",
        type:"POST",
        data: data1,
        enctype: 'multipart/form-data',
        processData: false, // tell jQuery not to process the data
        contentType: false // tell jQuery not to set contentType
    }).done(function(data) {
        console.log("PHP Output:");
        console.log(data);
    });
    return false;
}

PHP:

1
2
3
4
5
6
7
public function upload_file() {
    foreach($_FILES as $key) {
        $name = time().$key['name'];
        $path = 'upload/'.$name;
        @move_uploaded_file($key['tmp_name'], $path);
    }
}


而不是-fd.append( 'userfile', $('#userfile')[0].files[0]);

用途-fd.append( 'file', $('#userfile')[0].files[0]);


如果要使用Ajax提交文件,请使用"jquery.form.js"这很容易提交所有表单元素。

样品http://jquery.malsup.com/form/ajaxsubmit

粗略的看法:

1
<form id='AddPhotoForm' method='post' action='../photo/admin_save_photo.php' enctype='multipart/form-data'>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script type="text/javascript">
function showResponseAfterAddPhoto(responseText, statusText)
{
    information= responseText;
    callAjaxtolist();
    $("#AddPhotoForm").resetForm();
    $("#photo_msg").html('Photo uploaded Successfully...');        
};

$(document).ready(function(){
    $('.add_new_photo_div').live('click',function(){
            var options = {success:showResponseAfterAddPhoto};  
            $("#AddPhotoForm").ajaxSubmit(options);
        });
});

我找到的最好的文档和示例是:https://developer.mozilla.org/en-us/docs/web/guide/using_formdata_objects