如何发送FormData对象与ajax请求在jQuery?

XMLHttpRequest级别2标准(仍然是工作草案)定义了FormData接口。该接口允许将File对象追加到XHR-requests (Ajax-requests)。

顺便说一句,这是一个新功能-在过去,“隐藏的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请求的成功处理程序。

这在所有浏览器中都能很好地工作(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请求:

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

如您所见,内容类型是错误的……

1023148 次浏览

我相信你可以这样做:

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自动将数据转换为查询字符串。参见the docs了解更多信息。

  • contentType设置为false是必要的,否则jQuery 将不正确地设置

你可以使用$。ajax beforeSend事件来操作头部。

...

beforeSend: function(xhr) {
xhr.setRequestHeader('Content-Type', 'multipart/form-data');
}

...

有关更多信息,请参阅此链接:http://msdn.microsoft.com/en-us/library/ms536752 (v = vs.85) . aspx

这里有一些尚未被提及的技术可供您使用。首先在ajax参数中设置contentType属性。

以普拉迪克为例:

$('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事件是一个很好的地方。一段时间以来,人们使用beforeSend来覆盖mimeType,然后在1.5.1中添加到jQuery中。您应该能够在发送前事件中修改jqXHR对象上的任何内容。

如果你想使用ajax提交文件,请使用"jquery.form.js" 这将很容易地提交所有表单元素 < p >样品 # EYZ0 < / p >

粗略视图:

<form id='AddPhotoForm' method='post' action='../photo/admin_save_photo.php' enctype='multipart/form-data'>

< p > < br >

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

我这样做,这是我的工作,我希望这将有所帮助:)

   <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>

而不是- fd.append( 'userfile', $('#userfile')[0].files[0]);

使用- fd.append( 'file', $('#userfile')[0].files[0]);

你可以在ajax请求中使用以下代码发送FormData对象,

$("form#formElement").submit(function(){
var formData = new FormData($(this)[0]);
});

这与公认的答案非常相似,但却是对问题主题的实际答案。这将自动在FormData中提交表单元素,您不需要手动将数据附加到FormData变量中。

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

您还可以手动将form元素作为参数传递到FormData对象中,如下所示

var formElem = $("#formId");
var formdata = new FormData(formElem[0]);

希望能有所帮助。;)