如何在jQuery中发送Ajax请求的FormData对象?
XMLHttpRequest Level 2标准(仍然是一个工作草案)定义了FormData
接口。 这个接口可以将File
对象附加到XHR请求(Ajax请求)。
顺便说一句,这是一个新的function – 过去,使用“隐藏的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浏览器)美丽的作品。
现在,我想使这个function与jQuery的工作。 我试过这个:
var fd = new FormData(); fd.append( 'file', input.files[0] ); $.post( 'http://example.com/script.php', fd, handler );
不幸的是,这是行不通的(一个“非法调用”的错误引发 – 屏幕截图在这里 )。 我假设jQuery期望一个简单的键值对象表示form-field-names / values,而我传入的FormData
实例显然是不兼容的。
现在,因为可以将一个FormData
实例传递到xhr.send()
,所以我希望它也可以使用jQuery。
更新:
我在jQuery的Bug Tracker上创build了一个“特性票”。 它在这里: http : //bugs.jquery.com/ticket/9995
我被build议使用“Ajax预filter”…
更新:
首先,让我演示一下演示,我想实现什么样的行为。
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”内容types!
build议的解决scheme将如下所示:
$( '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(); });
但是,这导致:
正如你所看到的,内容types是错误的…
我相信你可以这样做:
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自动将数据转换为查询string。 有关更多信息,请参阅文档 。
将contentType
设置为false是非常必要的,否则jQuery 会将其设置错误 。
还有一些尚待提及的技术可供您使用。 首先在ajax参数中设置contentType属性。
以pradeek为例:
$('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(); });
在某些情况下,当强迫jQuery ajax做非预期的事情时, beforeSend
事件是一个很好的select。 一段时间beforeSend
,人们使用beforeSend
来重写mimeType,然后在1.5.1中添加到jQuery中。 您应该可以修改before发送事件中jqXHR对象的任何内容。
您可以使用以下代码发送Ajax请求中的FormData对象,
$("form#formElement").submit(function(){ var formdata = new FormData($(this)[0]); });
这与接受的答案非常相似,但是是对于问题主题的实际答案。 这将在FormData中自动提交表单元素,而不需要手动将数据附加到FormDatavariables。
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(form[0]);
希望它有帮助。 ;)
您可以使用$ .ajax beforeSend
事件来操作标题。
…
beforeSend: function(xhr) { xhr.setRequestHeader('Content-Type', 'multipart/form-data'); }
…
有关其他信息,请参阅此链接: http : //msdn.microsoft.com/zh-cn/library/ms536752(v=vs.85).aspx
我认为你不能在ajax中支持所有的浏览器,我可能会说很好,检查这个ajax上传插件,看看他们是如何做到的http://valums.com/ajax-upload/
我这样做,这对我来说,我希望这会帮助:)
<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>
如果你想使用ajax提交文件,使用“jquery.form.js”,这很容易提交所有的表单元素。
示例http://jquery.malsup.com/form/#ajaxSubmit
粗糙的看法:
<form id='AddPhotoForm' method='post' action='../photo/admin_save_photo.php' enctype='multipart/form-data'>
<script type="text/javascript"> function showResponseAfterAddPhoto(responseText, statusText) { information= responseText; callAjaxtolist(); $("#AddPhotoForm").resetForm(); $("#photo_msg").html('<div class="album_msg">Photo uploaded Successfully...</div>'); }; $(document).ready(function(){ $('.add_new_photo_div').live('click',function(){ var options = {success:showResponseAfterAddPhoto}; $("#AddPhotoForm").ajaxSubmit(options); }); }); </script>
JavaScript的:
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; }
PHP:
public function upload_file(){ foreach ($_FILES as $key ) { $name =time().$key['name']; $path='upload/'.$name; @move_uploaded_file($key['tmp_name'],$path); }
而不是 – fd.append( 'userfile', $('#userfile')[0].files[0]);
使用 – fd.append( 'file', $('#userfile')[0].files[0]);