我正在使用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>

当前回答

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

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

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

其他回答

问题是我使用了错误的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);
    });
});

一个简单但更有效的方法: new FormData()本身就像一个容器(或袋子)。你可以把所有attr或文件本身。 你唯一需要附加属性file fileName eg:

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

然后传入AJAX request。例如:

    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中使用AJAX请求从Script.js文件到Route文件,请注意使用 要求的事情。主体用于访问数据(即文本) 要求的事情。访问文件的文件(如图像、视频等)

编辑:在新版本的JQuery(3.6)中,你也可以尝试使用contentType函数参数来代替enctype。试试contentType: 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>

正如上面提到的,请特别注意contentType和processData字段。

在我的情况下,我必须发出一个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);

——DOT NET CORE MVC实现的解决方案—— 在看这个问题的时候,我想我应该正确的。net CORE实现,因为这个问题不是特定于任何后端语言。 这是独立实现的例子。 目标:-提交包括文件在内的表单字段,以及我们如何在后端单个模型中获得数据

HTML代码/视图代码- Views/Home/Index.cshtml

@{
    ViewData["Title"] = "Home Page";
}

<input type="file" id="FileUpload1" multiple />
<div>
    <label>Enter First Name :</label>
    <input type="text" id="nameText" maxlength="50" />

</div>
<input type="button" id="btnUpload" value="Submit Form with Files" />

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
    $(document).ready(function () {
        $('#btnUpload').click(function () {

            // Checking whether FormData is available in browser
            if (window.FormData !== undefined) {

                var fileUpload = $("#FileUpload1").get(0);
                var files = fileUpload.files;

                // Create FormData object
                var fileData = new FormData();

                // Looping over all files and add it to FormData object
                for (var i = 0; i < files.length; i++) {
                    fileData.append("files", files[i]);
                }
                // Adding one more key to FormData object
                fileData.append('FirstName', $("#nameText").val());

                $.ajax({
                    url: '/Home/UploadFiles',
                    type: "POST",
                    contentType: false, // Not to set any content header
                    processData: false, // Not to process data
                    data: fileData,
                    success: function (result) {
                        alert(result);
                    },
                    error: function (err) {
                        alert(err.statusText);
                    }
                });
            } else {
                alert("FormData is not supported.");
            }
        });
    });
</script>  

后台代码/控制器动作方法Controllers/ homeconcontroller .cs

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;
    private readonly IWebHostEnvironment _environment;

    public HomeController(ILogger<HomeController> logger, IWebHostEnvironment environment)
    {
        _logger = logger;
        _environment = environment;
    }

    public IActionResult Index()
    {
        return View();
    }

    public IActionResult Privacy()
    {
        return View();
    }

    [HttpPost]
    public async Task<IActionResult> UploadFiles(MyForm myForm)
    {
        var files = myForm.Files;
        // First Name 
        string name = myForm.FirstName;

        // check All files
        foreach (IFormFile source in files)
        {
            string filename = ContentDispositionHeaderValue.Parse(source.ContentDisposition).FileName.Trim('"');

            filename = this.EnsureCorrectFilename(filename);
            string fileWithPath = this.GetPathAndFilename(filename);
            // Create directory if not exist
            Directory.CreateDirectory(Path.GetDirectoryName(fileWithPath));

            using (FileStream output = System.IO.File.Create(fileWithPath))
                await source.CopyToAsync(output);
        }

        return Ok("Success");
    }

    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    public IActionResult Error()
    {
        return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
    }

    public class MyForm
    {
        public string FirstName { get; set; }
        public IList<IFormFile> Files { get; set; }
    }

    private string EnsureCorrectFilename(string filename)
    {
        if (filename.Contains("\\"))
            filename = filename.Substring(filename.LastIndexOf("\\") + 1);

        return filename;
    }

    private string GetPathAndFilename(string filename)
    {
        return Path.Combine(_environment.ContentRootPath, "uploadedFiles", filename);
    }
}

完整源代码回购:https://github.com/rj-learning/DotNetCoreFileUpload