如何异步上传文件?

JavaScript

Itachi小哥

2020-03-09

我想用jQuery异步上传文件。

$(document).ready(function () {
    $("#uploadbutton").click(function () {
        var filename = $("#file").val();

        $.ajax({
            type: "POST",
            url: "addFile.do",
            enctype: 'multipart/form-data',
            data: {
                file: filename
            },
            success: function () {
                alert("Data Uploaded: ");
            }
        });
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<span>File</span>
<input type="file" id="file" name="file" size="10"/>
<input id="uploadbutton" type="button" value="Upload"/>

我只获取文件名,而不是上传文件。我该怎么做才能解决此问题?

第164篇《如何异步上传文件?》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

9个回答
YOC96576526 2020.06.12

In Controller

[HttpPost] 
        public ActionResult UploadFiles()
        {
            if (Request.Files.Count > 0)
            {
                var files = Request.Files;

                //iterating through multiple file collection   
                foreach (string str in files)
                {
                    HttpPostedFileBase file = Request.Files[str] as HttpPostedFileBase;
                    //Checking file is available to save.  
                    if (file != null)
                    {
                        var InputFileName = Path.GetFileName(file.FileName);
                        var ServerSavePath = Path.Combine(Server.MapPath("~/Uploads/") + InputFileName);
                        //Save file to server folder  
                        file.SaveAs(ServerSavePath);
                       
                    }

                }
                return Json("File Uploaded Successfully!");
            }
            else
            {
                return Json("No files to upload");
            }
        }

Source : jQuery Ajax File upload MVC

File Upload in MVC

In View

$('#Upload').click(function () {     



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

            var files = fileUpload.files;



            // Create  a FormData object

            var fileData = new FormData();



            // if there are multiple files , loop through each files

            for (var i = 0; i < files.length; i++) {

                fileData.append(files[i].name, files[i]);

            }



            // Adding more keys/values here if need

            fileData.append('Test', "Test Object values");



            $.ajax({

                url: '/Home/UploadFiles', //URL to upload files 

                type: "POST", //as we will be posting files and other method POST is used

                processData: false, //remember to set processData and ContentType to false, otherwise you may get an error

                contentType: false,      

                data: fileData,

                success: function (result) {

                    alert(result);

                },

                error: function (err) {

                    alert(err.statusText);

                }

            });

         

    });			
Stafan路易 2020.03.09

您可以使用JavaScript或jQuery进行异步多个文件上传,而无需使用任何插件即可上传。您还可以在进度控件中显示文件上传的实时进度。我遇到了2个不错的链接-

  1. 具有进度条的基于ASP.NET Web窗体的多文件上传功能
  2. jQuery中基于ASP.NET MVC的多文件上传

服务器端语言是C#,但是您可以进行一些修改以使其与PHP等其他语言一起使用。

文件上传ASP.NET Core MVC:

在html中的“查看创建文件”上载控件中:

<form method="post" asp-action="Add" enctype="multipart/form-data">
    <input type="file" multiple name="mediaUpload" />
    <button type="submit">Submit</button>
</form>

现在在您的控制器中创建操作方法:

[HttpPost]
public async Task<IActionResult> Add(IFormFile[] mediaUpload)
{
    //looping through all the files
    foreach (IFormFile file in mediaUpload)
    {
        //saving the files
        string path = Path.Combine(hostingEnvironment.WebRootPath, "some-folder-path"); 
        using (var stream = new FileStream(path, FileMode.Create))
        {
            await file.CopyToAsync(stream);
        }
    }
}

HostingEnvironment变量的类型为IHostingEnvironment,可以使用依赖项注入将其注入到控制器中,例如:

private IHostingEnvironment hostingEnvironment;
public MediaController(IHostingEnvironment environment)
{
    hostingEnvironment = environment;
}
LEYJim 2020.03.09

使用HTML5JavaScript,上传异步非常容易,我与html一起创建了上传逻辑,由于需要api,因此无法完全正常工作,但是如果您有/upload从网站根目录调用的终结点,请演示其工作原理,该代码应为您工作:

const asyncFileUpload = () => {
  const fileInput = document.getElementById("file");
  const file = fileInput.files[0];
  const uri = "/upload";
  const xhr = new XMLHttpRequest();
  xhr.upload.onprogress = e => {
    const percentage = e.loaded / e.total;
    console.log(percentage);
  };
  xhr.onreadystatechange = e => {
    if (xhr.readyState === 4 && xhr.status === 200) {
      console.log("file uploaded");
    }
  };
  xhr.open("POST", uri, true);
  xhr.setRequestHeader("X-FileName", file.name);
  xhr.send(file);
}
<form>
  <span>File</span>
  <input type="file" id="file" name="file" size="10" />
  <input onclick="asyncFileUpload()" id="upload" type="button" value="Upload" />
</form>

还提供有关XMLHttpReques的更多信息:

XMLHttpRequest对象

所有现代浏览器都支持XMLHttpRequest对象。XMLHttpRequest对象可用于与后台的Web服务器交换数据。这意味着可以更新网页的某些部分,而无需重新加载整个页面。


创建一个XMLHttpRequest对象

所有现代浏览器(Chrome,Firefox,IE7 +,Edge,Safari,Opera)都具有内置的XMLHttpRequest对象。

创建XMLHttpRequest对象的语法:

变量=新的XMLHttpRequest();


跨域访问

出于安全原因,现代浏览器不允许跨域访问。

这意味着该网页及其尝试加载的XML文件都必须位于同一服务器上。

W3Schools上的示例位于W3Schools域上的所有打开的XML文件。

如果要在自己的一个网页上使用上面的示例,则加载的XML文件必须位于自己的服务器上。

有关更多详细信息,您可以在此处继续阅读...

猴子小宇宙 2020.03.09

|使用HTML5的readAsDataURL()某些base64编码器将文件转换为base64 在这里摆弄

var reader = new FileReader();

        reader.onload = function(readerEvt) {
            var binaryString = readerEvt.target.result;
            document.getElementById("base64textarea").value = btoa(binaryString);
        };

        reader.readAsBinaryString(file);

然后检索:

window.open("data:application/octet-stream;base64," + base64);
神奇Jim 2020.03.09

您可以在此处看到带有有效演示的解决方案,可以预览表单文件并将其提交到服务器。对于您的情况,您需要使用Ajax来方便将文件上传到服务器:

<from action="" id="formContent" method="post" enctype="multipart/form-data">
    <span>File</span>
    <input type="file" id="file" name="file" size="10"/>
    <input id="uploadbutton" type="button" value="Upload"/>
</form>

提交的数据是一个formdata。在您的jQuery上,使用表单提交功能而不是单击按钮来提交表单文件,如下所示。

$(document).ready(function () {
   $("#formContent").submit(function(e){

     e.preventDefault();
     var formdata = new FormData(this);

 $.ajax({
     url: "ajax_upload_image.php",
     type: "POST",
     data: formdata,
     mimeTypes:"multipart/form-data",
     contentType: false,
     cache: false,
     processData: false,
     success: function(){

     alert("successfully submitted");

     });
   });
});

查看更多细节

猿小宇宙小哥 2020.03.09

我发现的解决方案是将<form>目标设为隐藏的iFrame。然后,iFrame可以运行JS以向用户显示其已完成(页面加载时)。

A小卤蛋Pro 2020.03.09

注意:此答案已过时,现在可以使用XHR上传文件。


您不能使用XMLHttpRequest(Ajax)上传文件您可以使用iframe或Flash模拟效果。出色的jQuery表单插件,可通过iframe发布文件以获得效果。

飞云小胖 2020.03.09

2019更新:它仍然取决于您的人口统计使用的浏览器

使用“新” HTML5 fileAPI 需了解的重要一点是,直到IE 10才支持如果您瞄准的特定市场对较旧版本的Windows具有高于平均水平的倾向,则您可能无权使用它。

截至2017年,大约5%的浏览器是IE 6、7、8或9之一。如果您进入一家大公司(例如,这是B2B工具,或者您要提供培训的内容),那么这个数字可能会飙升。2016年,我与一家使用IE8的公司进行了交易,这些公司的机器中有60%以上使用IE8。

截至本次编辑截止到2019年,距我最初的回答已经过去11年了。IE9及更低版本在全球范围内均在1%左右,但仍存在使用率更高的集群。

最重要的外卖从这个-whatever的特征-是检查什么的浏览器用户使用如果您不这样做,您将学到一个快速而痛苦的课程,以了解为什么“为我工作”在交付给客户的产品中不够好。caniuse是一个有用的工具,但请注意他们从哪里获得人口统计信息。它们可能与您的不一致。这从未比企业环境真实。

我在2008年的回答如下。


但是,存在可行的非JS文件上传方法。您可以在页面上创建一个iframe(使用CSS隐藏该iframe),然后将表单定位为发布到该iframe。主页不需要移动。

这是一个“真实”的帖子,因此并不完全是交互式的。如果您需要状态,则需要服务器端进行处理。具体取决于您的服务器。ASP.NET具有更好的机制。PHP Plain失败了,但是您可以使用Perl或Apache修改来解决它。

如果需要多个文件上传,则最好一次执行一个文件(以克服最大文件上传限制)。将第一个表单发布到iframe中,使用上述方法监视进度,完成后,将第二个表单发布到iframe中,依此类推。

或使用Java / Flash解决方案。他们可以更灵活地处理自己的帖子...

Gil伽罗小宇宙 2020.03.09

我建议为此使用Fine Uploader插件。您的JavaScript代码为:

$(document).ready(function() {
  $("#uploadbutton").jsupload({
    action: "addFile.do",
    onComplete: function(response){
      alert( "server response: " + response);
    }
  });
});

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android