Javascript 如何在jQuery中使用Ajax请求发送FormData对象?

Javascript 如何在jQuery中使用Ajax请求发送FormData对象?,javascript,jquery,ajax,html,multipartform-data,Javascript,Jquery,Ajax,Html,Multipartform Data,该标准(仍然是一个工作草案)定义了FormData接口。此接口支持将文件对象附加到XHR请求(Ajax请求)中 顺便说一句,这是一个新功能-在过去,使用了“隐藏iframe技巧”(请参阅中的) 这就是它的工作原理(示例): 其中,input是一个字段,handler是Ajax请求的成功处理程序 这在所有浏览器中都能很好地工作(同样,IE除外) 现在,我想让这个功能与jQuery一起工作。我试过这个: var fd = new FormData(); fd.append( 'file',

该标准(仍然是一个工作草案)定义了
FormData
接口。此接口支持将
文件
对象附加到XHR请求(Ajax请求)中

顺便说一句,这是一个新功能-在过去,使用了“隐藏iframe技巧”(请参阅中的)

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

其中,
input
是一个
字段,
handler
是Ajax请求的成功处理程序

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

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

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

$.post( 'http://example.com/script.php', fd, handler );
不幸的是,这不起作用(抛出“非法调用”错误-)。我假设jQuery需要一个表示表单字段名称/值的简单键值对象,而我传递的
FormData
实例显然是不兼容的

现在,由于可以将
FormData
实例传递到
xhr.send()
,因此我希望也可以使用jQuery


更新:

我在jQuery的Bug跟踪器上创建了一个“功能标签”。在这里:

有人建议我使用“Ajax预过滤器”


更新:

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

HTML:

上述代码导致此HTTP请求:

这就是我需要的-我想要那种“多部分/表单数据”的内容类型


拟议的解决办法如下:

$( '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();
});
然而,这导致:


如您所见,内容类型错误…

我相信您可以这样做:

var fd=new FormData();
fd.append('file',input.files[0]);
$.ajax({
网址:'http://example.com/script.php',
数据:fd,
processData:false,
contentType:false,
键入:“POST”,
成功:功能(数据){
警报(数据);
}
});
注:

  • processData
    设置为
    false
    可以防止jQuery自动将数据转换为查询字符串。有关更多信息,请参阅

  • contentType
    设置为
    false
    是必须的,否则jQuery将失败


您可以使用$.ajax
beforeSend
事件来操作标头


有关更多信息,请参见此链接:

您可以使用一些有待提及的技术。首先在ajax参数中设置contentType属性

以pradeek的例子为基础:

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 );
$('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();
});

在某些情况下,当强制jqueryajax执行非预期的操作时,
beforeSend
事件是执行此操作的好地方。有一段时间,人们使用
beforeSend
覆盖mimeType,然后在1.5.1中将其添加到jQuery中。您应该能够在before send事件中修改jqXHR对象上的任何内容。

如果您想使用ajax提交文件,请使用“jquery.form.js” 这样可以轻松提交所有表单元素

样品

大致情况:

<form id='AddPhotoForm' method='post' action='../photo/admin_save_photo.php' enctype='multipart/form-data'>



函数showResponseAfterAddPhoto(responseText、statusText)
{ 
信息=响应文本;
callAjaxtolist();
$(“#AddPhotoForm”).resetForm();
$(“#photo_msg”).html('照片上传成功…');
};
$(文档).ready(函数(){
$('.add_new_photo_div').live('click',function(){
var options={success:showResponseAfterAddPhoto};
$(“#AddPhotoForm”).ajaxSubmit(可选);
});
});
JavaScript:

$( '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();
});
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;
}

我就是这样做的,这对我来说很有用,我希望这会有所帮助:)




$(文档).ready(函数(){ $(“#上载”)。单击(函数(){ console.log('单击上载按钮!') var fd=新FormData(); fd.append('userfile',$('#userfile')[0].files[0]); $.ajax({ url:“上传/不上传”, 数据:fd, processData:false, contentType:false, 键入:“POST”, 成功:功能(数据){ console.log('upload success!') $(“#数据”).empty(); $(“#数据”)。追加(数据); } }); }); });
而不是-
fd.append('userfile',$('userfile')[0]。files[0])


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

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

$("form#formElement").submit(function(){
    var formData = new FormData($(this)[0]);
});
这与公认的答案非常相似,但却是问题主题的实际答案。这将在FormData中自动提交表单元素,您无需手动将数据附加到FormData变量

ajax方法如下所示

$("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对象内的form元素作为如下参数传递

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

希望有帮助

对!!这是个好主意!谢谢你提供的信息。我最近发现了一个代码段,它可以做到这一点,但它不是jQuery,我想知道jQuery是否可以做到这一点。对我来说,这与其说是一个问题,不如说是一个答案。随时通知我们!现在,如果我/我们知道在所说的预滤器中放入什么就好了。这里的情况也一样。任何人还有什么线索吗?@zaf Setting
processData:false
是朝着正确方向迈出的一步(参见pradeek提出的解决方案)。现在,如果我可以手动设置“内容类型”HTTP请求头。。。有关详细信息,请参阅我更新的问题。您的问题在这里没有得到回答吗?不幸的是,这会导致设置错误的“内容类型”HTTP请求头。请参阅我的问题,以详细解释我想要实现的目标以及当前解决方案不能满足您需求的原因。
public function upload_file() {
    foreach($_FILES as $key) {
        $name = time().$key['name'];
        $path = 'upload/'.$name;
        @move_uploaded_file($key['tmp_name'], $path);
    }
}
   <div id="data">
        <form>
            <input type="file" name="userfile" id="userfile" size="20" />
            <br /><br />
            <input type="button" id="upload" value="upload" />
        </form>
    </div>
  <script>
        $(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);

                      }
                    });
                });
        });
    </script>   
$("form#formElement").submit(function(){
    var formData = new FormData($(this)[0]);
});
$("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
        },
});
var formElem = $("#formId");
var formdata = new FormData(formElem[0]);