这是它的工作原理(示例):
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 );
whereinput是一个<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
现在,既然可以将FormData实例传递给xhr.send(),我希望它也可以与 jQuery 一起使用。
xhr.send()
更新:
我在 jQuery 的 Bug Tracker 上创建了一个“功能票”。它在这里: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(); });
但是,这会导致:
如您所见,内容类型错误…
我相信你可以这样做:
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
设置contentTypetofalse是必要的,否则 jQuery会错误地设置它
contentType