XMLHttpRequest的2级标准(还是一个工作草案)定义FormData的接口。该接口允许将File对象附加到XHR请求(Ajax请求)。
File
顺便说一句,这是一个新功能-过去曾使用过“ hidden-iframe-trick”(请在我的另一个问题中阅读)。
“ 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是<input type="file">字段,并且handler是Ajax请求的成功处理者。
input
<input type="file">
handler
在所有浏览器中(同样,除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一起使用。
建议我使用“ Ajax预过滤器” …
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请求:
多部分数据
这就是我需要的 -我想要“多部分/表单数据”内容类型!
提议的解决方案如下所示:
$( '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({ url: 'http://example.com/script.php', data: fd, processData: false, contentType: false, type: 'POST', success: function(data){ alert(data); } });
笔记:
设置processData为false可以防止jQuery自动将数据转换为查询字符串。有关更多信息,请参阅文档。
processData
false
设置contentType to false为当务之急,因为否则jQuery 会错误地设置它。
contentType to false