使用Ajax在一个表单中上传数据和文件?

我正在使用jQuery和Ajax为我的表单提交数据和文件,但我不知道如何在一个表单中发送数据和文件?

我目前做的几乎相同的两种方法,但数据收集到数组的方式是不同的,数据使用.serialize();,但文件使用= new FormData($(this)[0]);

是否有可能结合这两种方法,以便通过Ajax以一种形式上传文件和数据?

数据jQuery, Ajax和html

$("form#data").submit(function(){


var formData = $(this).serialize();


$.ajax({
url: window.location.pathname,
type: 'POST',
data: formData,
async: false,
success: function (data) {
alert(data)
},
cache: false,
contentType: false,
processData: false
});


return false;
});


<form id="data" method="post">
<input type="text" name="first" value="Bob" />
<input type="text" name="middle" value="James" />
<input type="text" name="last" value="Smith" />
<button>Submit</button>
</form>

jQuery, Ajax和html文件

$("form#files").submit(function(){


var formData = new FormData($(this)[0]);


$.ajax({
url: window.location.pathname,
type: 'POST',
data: formData,
async: false,
success: function (data) {
alert(data)
},
cache: false,
contentType: false,
processData: false
});


return false;
});


<form id="files" method="post" enctype="multipart/form-data">
<input name="image" type="file" />
<button>Submit</button>
</form>

如何结合上述内容,以便通过Ajax以一种形式发送数据和文件?

我的目标是能够发送所有这些表单在一个帖子与Ajax,这是可能的吗?

<form id="datafiles" method="post" enctype="multipart/form-data">
<input type="text" name="first" value="Bob" />
<input type="text" name="middle" value="James" />
<input type="text" name="last" value="Smith" />
<input name="image" type="file" />
<button>Submit</button>
</form>
701159 次浏览

问题是我使用了错误的jQuery标识符。

你可以用一个表单使用ajax能否上传数据和文件

PHP + HTML

<?php


print_r($_POST);
print_r($_FILES);
?>


<form id="data" method="post" enctype="multipart/form-data">
<input type="text" name="first" value="Bob" />
<input type="text" name="middle" value="James" />
<input type="text" name="last" value="Smith" />
<input name="image" type="file" />
<button>Submit</button>
</form>

jQuery + Ajax

$("form#data").submit(function(e) {
e.preventDefault();
var formData = new FormData(this);


$.ajax({
url: window.location.pathname,
type: 'POST',
data: formData,
success: function (data) {
alert(data)
},
cache: false,
contentType: false,
processData: false
});
});

短的版本

$("form#data").submit(function(e) {
e.preventDefault();
var formData = new FormData(this);


$.post($(this).attr("action"), formData, function(data) {
alert(data);
});
});

或更短:

$("form#data").submit(function() {
var formData = new FormData(this);
$.post($(this).attr("action"), formData, function() {
// success
});
return false;
});

另一种选择是使用iframe并将表单的目标设置为iframe。

你可以试试这个(它使用jQuery):

function ajax_form($form, on_complete)
{
var iframe;


if (!$form.attr('target'))
{
//create a unique iframe for the form
iframe = $("<iframe></iframe>").attr('name', 'ajax_form_' + Math.floor(Math.random() * 999999)).hide().appendTo($('body'));
$form.attr('target', iframe.attr('name'));
}


if (on_complete)
{
iframe = iframe || $('iframe[name="' + $form.attr('target') + '"]');
iframe.load(function ()
{
//get the server response
var response = iframe.contents().find('body').text();
on_complete(response);
});
}
}

它适用于所有浏览器,你不需要序列化或准备数据。 一个缺点是你不能监控进度

另外,至少对于chrome浏览器,请求不会出现在开发工具的“xhr”标签下,而是在“doc”下。

我在ASP中也遇到了同样的问题。Net MVC和HttpPostedFilebase,而不是在提交上使用表单,我需要使用按钮,点击,我需要做一些事情,然后如果都OK,提交表单,这是我如何让它工作

$(".submitbtn").on("click", function(e) {


var form = $("#Form");


// you can't pass Jquery form it has to be javascript form object
var formData = new FormData(form[0]);


//if you only need to upload files then
//Grab the File upload control and append each file manually to FormData
//var files = form.find("#fileupload")[0].files;


//$.each(files, function() {
//  var file = $(this);
//  formData.append(file[0].name, file[0]);
//});


if ($(form).valid()) {
$.ajax({
type: "POST",
url: $(form).prop("action"),
//dataType: 'json', //not sure but works for me without this
data: formData,
contentType: false, //this is requireded please see answers above
processData: false, //this is requireded please see answers above
//cache: false, //not sure but works for me without this
error   : ErrorHandler,
success : successHandler
});
}
});

这将比正确地填充你的MVC模型,请确保在你的模型,属性HttpPostedFileBase[]有相同的名称作为html中的输入控件的的名字

<input id="fileupload" type="file" name="UploadedFiles" multiple>


public class MyViewModel
{
public HttpPostedFileBase[] UploadedFiles { get; set; }
}

下面的代码适合我

$(function () {
debugger;
document.getElementById("FormId").addEventListener("submit", function (e) {
debugger;
if (ValidDateFrom()) { // Check Validation
var form = e.target;
if (form.getAttribute("enctype") === "multipart/form-data") {
debugger;
if (form.dataset.ajax) {
e.preventDefault();
e.stopImmediatePropagation();
var xhr = new XMLHttpRequest();
xhr.open(form.method, form.action);
xhr.onreadystatechange = function (result) {
debugger;
if (xhr.readyState == 4 && xhr.status == 200) {
debugger;
var responseData = JSON.parse(xhr.responseText);
SuccessMethod(responseData); // Redirect to your Success method
}
};
xhr.send(new FormData(form));
}
}
}
}, true);
});
在Action Post方法中,将参数传递为HttpPostedFileBase UploadFile,并确保您的文件输入与Action方法的参数中提到的相同。

记住在这里,你的AJAX BEGIN表单将不会在这里工作,因为你在上面提到的代码中定义了你的post调用,你可以根据需求在代码中引用你的方法

我知道我回答得晚了,但这对我来说是有效的

<form id="form" method="post" action="otherpage.php" enctype="multipart/form-data">
<input type="text" name="first" value="Bob" />
<input type="text" name="middle" value="James" />
<input type="text" name="last" value="Smith" />
<input name="image" type="file" />
<button type='button' id='submit_btn'>Submit</button>
</form>


<script>
$(document).on("click", "#submit_btn", function (e) {
//Prevent Instant Click
e.preventDefault();
// Create an FormData object
var formData = $("#form").submit(function (e) {
return;
});
//formData[0] contain form data only
// You can directly make object via using form id but it require all ajax operation inside $("form").submit(<!-- Ajax Here   -->)
var formData = new FormData(formData[0]);
$.ajax({
url: $('#form').attr('action'),
type: 'POST',
data: formData,
success: function (response) {
console.log(response);
},
contentType: false,
processData: false,
cache: false
});
return false;
});
</script>


/ / / / / otherpage.php

<?php
print_r($_FILES);
?>

编辑:在新版本的JQuery (3.6)中,你也可以尝试使用contentType函数参数来代替enctypecontentType: multipart/form-data试试。


对我来说,在Ajax请求中没有enctype: 'multipart/form-data'字段是不行的。我希望它能帮助那些陷入类似问题的人。

尽管enctype 是否已经在表单属性中设置,由于某些原因,Ajax请求没有显式声明就不能自动识别enctype (jQuery 3.3.1)。

// Tested, this works for me (jQuery 3.3.1)


fileUploadForm.submit(function (e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: $(this).attr('action'),
enctype: 'multipart/form-data',
data: new FormData(this),
processData: false,
contentType: false,
success: function (data) {
console.log('Thank God it worked!');
}
}
);
});


// enctype field was set in the form but Ajax request didn't set it by default.


<form action="process/file-upload" enctype="multipart/form-data" method="post" >
     

<input type="file" name="input-file" accept="text/plain" required>
...
</form>

如上所述,请特别注意contentTypeprocessData字段。

在我的情况下,我必须发出一个POST请求,其中有通过头发送的信息,以及使用FormData对象发送的文件。

我使用这里的一些答案的组合使它工作,所以基本上最终工作的是在我的Ajax请求中有这五行:

 contentType: "application/octet-stream",
enctype: 'multipart/form-data',
contentType: false,
processData: false,
data: formData,

其中formData是一个这样创建的变量:

 var file = document.getElementById('uploadedFile').files[0];
var form = $('form')[0];
var formData = new FormData(form);
formData.append("File", file);
一个简单但更有效的方法:
new FormData()本身就像一个容器(或一个袋子)。你可以把所有attr或文件本身。 你唯一需要附加attribute, file, fileName的东西,例如:

let formData = new FormData()
formData.append('input', input.files[0], input.files[0].name)

然后传入AJAX request。如:< br >

    let formData = new FormData()
var d = $('#fileid')[0].files[0]


formData.append('fileid', d);
formData.append('inputname', value);


$.ajax({
url: '/yourroute',
method: 'POST',
contentType: false,
processData: false,
data: formData,
success: function(res){
console.log('successfully')
},
error: function(){
console.log('error')
}
})

你可以用FormData附加n个文件或数据。

,如果你在Node.js中从Script.js文件向Route文件发出AJAX请求,请注意使用
req.body访问数据(即文本)
req.files访问文件(即图像,视频等)

你可以把它们附加到你的formdata上,把你的文件和数据添加进去。你可以看看这个。

https://developer.mozilla.org/en-US/docs/Web/API/FormData/append

为了更好地理解。你可以分别获取$_FILES文件和$_POST数据。

这是我实现的一个解决方案

var formData = new FormData();
var files = $('input[type=file]');
for (var i = 0; i < files.length; i++) {
if (files[i].value == "" || files[i].value == null) {
return false;
}
else {
formData.append(files[i].name, files[i].files[0]);
}
}
var formSerializeArray = $("#Form").serializeArray();
for (var i = 0; i < formSerializeArray.length; i++) {
formData.append(formSerializeArray[i].name, formSerializeArray[i].value)
}
$.ajax({
type: 'POST',
data: formData,
contentType: false,
processData: false,
cache: false,
url: '/Controller/Action',
success: function (response) {
if (response.Success == true) {
return true;
}
else {
return false;
}
},
error: function () {
return false;
},
failure: function () {
return false;
}
});

只是提醒一下,在2022年你不需要使用jquery。尝试js标准的获取API

    var formData = new FormData(this);


fetch(url, {
method: 'POST',
body: formData
})
.then(response => {
if(response.ok) {
//success
alert(response);
} else {
throw Error('Server error');
}
})
.catch(error => {
console.log('fail', error);
});