问题

This question already has an answer here:

XMLHttpRequest Level 2 标准(仍然是工作草稿)定义了 FormData 界面.此接口允许将 File 对象附加到XHR请求(Ajax请求).

Btw,这是一个新功能 - 在过去,使用"hidden-iframe-trick"(在我的其他问题).

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

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 type ="file"> 字段, handler 是Ajax的成功处理程序-request.

这在所有浏览器(再次,除了IE)美妙地工作.

现在,我想使这个功能与jQuery一起使用.我试过这个:

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

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

很遗憾,这将无法正常工作(引发了"非法调用"错误 - 屏幕截图在此处< a>).我假设jQuery期望一个简单的键值对象表示form-field-names / values,和我传递的 FormData 实例显然是不兼容的.

现在,由于可以将 FormData 实例传递给 xhr.send(),我希望它也可以使用jQuery. / p>


更新:

我在jQuery的Bug Tracker上创建了一个"功能票".位于此处: http://bugs.jquery.com/ticket/9995

我建议使用"Ajax prefilter"...


更新:

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

HTML:

<form>
    <input type="file" id="file" name="file">
    <input type="submit">
</form>

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

上述代码导致此HTTP请求:

multipartformdata

这是我需要的 - 我想要"multipart / form-data"内容类型!


建议的解决方案如下:

$( '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

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



解决方法

我相信你可以这样做:

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 将设置不正确.




相关问题推荐