XMLHttpRequest Level 2标准(仍是工作草案)定义了FormData
接口,该接口使得可以将File
对象附加到XHR请求(Ajax请求)中。
顺便说一下,这是一个新功能-在过去,“隐藏的iframe技巧”被使用(可以在我的另一个问题中阅读有关此方法的信息)。
以下是其工作方式(示例):
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 请求的成功处理程序。
在所有浏览器中均可正常工作(除了 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跟踪器上创建了一个“特性票”,地址在这里:http://bugs.jquery.com/ticket/9995
有人建议我使用“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请求:
我需要的是 "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();
});
然而,这将导致:
正如您所看到的,内容类型是错误的...
processData:false
是朝着正确方向迈出的一步(请参考pradeek提出的解决方案)。现在,如果我能手动设置“Content-Type”HTTP请求头……请查看我的更新问题以获取详细信息。 - Šime Vidas