javascript - formdata - jquery upload file ajax




如何异步上传文件? (20)

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

使用“新”HTML5 file API需要了解的重要事项是IE 10之前不支持 。 如果您所针对的特定市场对旧版Windows的倾向高于平均水平,则可能无法访问它。

进入2017年,大约5%的浏览器是IE 6,7,8或9中的一个。如果你进入一家大公司(例如,这是一个B2B工具,或者你正在提供培训的东西),那么这个数字可能会火上浇油。 就在几个月前 - 在2016年 - 我在超过60%的机器上使用IE8处理了一家公司。

因此,在您执行任何操作之前: 检查用户使用的浏览器 。 如果你不这样做,你将学到一个快速而痛苦的教训,为什么“为我工作”对于客户的交付是不够的。

我的答案是从2008年开始的。

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

这是一个“真正的”帖子,所以它不是完全互动的。 如果您需要状态,则需要服务器端进行处理。 这根据您的服务器而有很大差异。 ASP.NET具有更好的机制。 PHP plain失败,但您可以使用Perl或Apache修改来绕过它。

如果您需要多个文件上传,最好一次执行一个文件(以克服最大文件上载限制)。 将第一个表单发布到iframe,使用上面的内容监控其进度,完成后,将第二个表单发布到iframe,依此类推。

或者使用Java / Flash解决方案。 他们对帖子的处理方式更加灵活......

我想用jQuery异步上传一个文件。 这是我的HTML:

<span>File</span>
<input type="file" id="file" name="file" size="10"/>
<input id="uploadbutton" type="button" value="Upload"/>

在这里我的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: ");
            }
        });
    });
});

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

当前解决方案

我正在使用jQuery Form Plugin上传文件。


jQuery Uploadify是我之前用来上传文件的另一个好插件。 JavaScript代码与以下内容一样简单:代码。 但是,新版本在Internet Explorer中不起作用。

$('#file_upload').uploadify({
    'swf': '/public/js/uploadify.swf',
    'uploader': '/Upload.ashx?formGuid=' + $('#formGuid').val(),
    'cancelImg': '/public/images/uploadify-cancel.png',
    'multi': true,
    'onQueueComplete': function (queueData) {
        // ...
    },
    'onUploadStart': function (file) {
        // ...
    }
});

我已经做了很多搜索,我已经找到了另一个没有任何插件上传文件的解决方案,只有ajax。 解决方案如下:

$(document).ready(function () {
    $('#btn_Upload').live('click', AjaxFileUpload);
});

function AjaxFileUpload() {
    var fileInput = document.getElementById("#Uploader");
    var file = fileInput.files[0];
    var fd = new FormData();
    fd.append("files", file);
    var xhr = new XMLHttpRequest();
    xhr.open("POST", 'Uploader.ashx');
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
             alert('success');
        }
        else if (uploadResult == 'success')
            alert('error');
    };
    xhr.send(fd);
}

为未来的读者做好准备。

异步文件上传

使用HTML5

如果支持FormDataFile API (两种HTML5功能),您可以使用$.ajax()方法使用jQuery上传文件。

您也可以在没有FormData的情况下发送文件但无论是哪种方式,都必须存在File API来处理文件,以便可以使用XMLHttpRequest (Ajax)发送文件。

$.ajax({
  url: 'file/destination.html', 
  type: 'POST',
  data: new FormData($('#formWithFiles')[0]), // The form with the file inputs.
  processData: false,
  contentType: false                    // Using FormData, no need to process data.
}).done(function(){
  console.log("Success: Files sent!");
}).fail(function(){
  console.log("An error occurred, the files couldn't be sent!");
});

有关快速,纯JavaScript( 无jQuery )示例,请参阅“ 使用FormData对象发送文件 ”。

倒退

当不支持HTML5(没有File API )时,唯一的其他纯JavaScript解决方案(没有Flash或任何其他浏览器插件)是隐藏的iframe技术,它允许在不使用XMLHttpRequest对象的情况下模拟异步请求。

它包括使用文件输入将iframe设置为表单的目标。 当用户提交请求并上传文件但响应显示在iframe内部而不是重新呈现主页面时。 隐藏iframe使整个过程对用户透明并模拟异步请求。

如果操作正确,它应该在任何浏览器上虚拟工作,但它有一些警告如何从iframe获取响应。

在这种情况下,您可能更喜欢使用像Bifröst这样的包装器插件,它使用iframe技术,但也提供了一个jQuery Ajax传输,允许仅使用$.ajax()方法发送文件 ,如下所示:

$.ajax({
  url: 'file/destination.html', 
  type: 'POST',
  // Set the transport to use (iframe means to use Bifröst)
  // and the expected data type (json in this case).
  dataType: 'iframe json',                                
  fileInputs: $('input[type="file"]'),  // The file inputs containing the files to send.
  data: { msg: 'Some extra data you might need.'}
}).done(function(){
  console.log("Success: Files sent!");
}).fail(function(){
  console.log("An error occurred, the files couldn't be sent!");
});

插件

Bifröst只是一个小包装器,它为jQuery的ajax方法添加了后备支持,但许多上述插件如jQuery Form Plugin或jQuery File Upload包括从HTML5到不同后备的整个堆栈以及一些有用的功能来简化过程。 根据您的需求和要求,您可能需要考虑裸实现或此插件中的任何一个。


你可以很容易地在vanilla JavaScript中完成它。 这是我当前项目的一个片段:

var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function(e) {
    var percent = (e.position/ e.totalSize);
    // Render a pretty progress bar
};
xhr.onreadystatechange = function(e) {
    if(this.readyState === 4) {
        // Handle file upload complete
    }
};
xhr.open('POST', '/upload', true);
xhr.setRequestHeader('X-FileName',file.name); // Pass the filename along
xhr.send(file);

您只需使用jQuery .ajax()上传即可。

HTML:

<form id="upload-form">
    <div>
        <label for="file">File:</label>
        <input type="file" id="file" name="file" />
        <progress class="progress" value="0" max="100"></progress>
    </div>
    <hr />
    <input type="submit" value="Submit" />
</form>

CSS

.progress { display: none; }

使用Javascript:

$(document).ready(function(ev) {
    $("#upload-form").on('submit', (function(ev) {
        ev.preventDefault();
        $.ajax({
            xhr: function() {
                var progress = $('.progress'),
                    xhr = $.ajaxSettings.xhr();

                progress.show();

                xhr.upload.onprogress = function(ev) {
                    if (ev.lengthComputable) {
                        var percentComplete = parseInt((ev.loaded / ev.total) * 100);
                        progress.val(percentComplete);
                        if (percentComplete === 100) {
                            progress.hide().val(0);
                        }
                    }
                };

                return xhr;
            },
            url: 'upload.php',
            type: 'POST',
            data: new FormData(this),
            contentType: false,
            cache: false,
            processData: false,
            success: function(data, status, xhr) {
                // ...
            },
            error: function(xhr, status, error) {
                // ...
            }
       });
    }));
});

您可以使用

$(function() {
    $("#file_upload_1").uploadify({
        height        : 30,
        swf           : '/uploadify/uploadify.swf',
        uploader      : '/uploadify/uploadify.php',
        width         : 120
    });
});

Demo


我建议使用Fine Uploader插件来实现此目的。 您的JavaScript代码将是:

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

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




简单的Ajax Uploader是另一种选择:

https://github.com/LPology/Simple-Ajax-Uploader

  • 跨浏览器 - 适用于IE7 +,Firefox,Chrome,Safari,Opera
  • 支持多个并发上传 - 即使在非HTML5浏览器中也是如此
  • 没有闪存或外部CSS - 只有一个5Kb的Javascript文件
  • 完全跨浏览器进度条的可选内置支持(使用PHP的APC扩展)
  • 灵活且高度可定制 - 使用任何元素作为上传按钮,设置您自己的进度指示器的样式
  • 无需表单,只需提供一个用作上传按钮的元素即可
  • 麻省理工学院许可证 - 免费用于商业项目

用法示例:

var uploader = new ss.SimpleUpload({
    button: $('#uploadBtn'), // upload button
    url: '/uploadhandler', // URL of server-side upload handler
    name: 'userfile', // parameter name of the uploaded file
    onSubmit: function() {
        this.setProgressBar( $('#progressBar') ); // designate elem as our progress bar
    },
    onComplete: function(file, response) {
        // do whatever after upload is finished
    }
});

要使用Jquery异步上传文件,请使用以下步骤:

步骤1在你的项目中打开Nuget管理器并添加包(jquery fileupload(只需要在搜索框中编写它就会出现并安装它。)URL:https://github.com/blueimp/jQuery-File-上传

步骤2在HTML文件中添加以下脚本,这些脚本已通过运行上面的包添加到项目中:

jquery.ui.widget.js

jquery.iframe-transport.js

jquery.fileupload.js

步骤3按以下代码编写文件上传控件:

<input id="upload" name="upload" type="file" />

第4步将js方法写为uploadFile,如下所示:

 function uploadFile(element) {

            $(element).fileupload({

                dataType: 'json',
                url: '../DocumentUpload/upload',
                autoUpload: true,
                add: function (e, data) {           
                  // write code for implementing, while selecting a file. 
                  // data represents the file data. 
                  //below code triggers the action in mvc controller
                  data.formData =
                                    {
                                     files: data.files[0]
                                    };
                  data.submit();
                },
                done: function (e, data) {          
                   // after file uploaded
                },
                progress: function (e, data) {

                   // progress
                },
                fail: function (e, data) {

                   //fail operation
                },
                stop: function () {

                  code for cancel operation
                }
            });

        };

步骤5在ready函数调用元素文件上传中,按以下方式启动进程:

$(document).ready(function()
{
    uploadFile($('#upload'));

});

步骤6按以下方式编写MVC控制器和操作:

public class DocumentUploadController : Controller
    {       

        [System.Web.Mvc.HttpPost]
        public JsonResult upload(ICollection<HttpPostedFileBase> files)
        {
            bool result = false;

            if (files != null || files.Count > 0)
            {
                try
                {
                    foreach (HttpPostedFileBase file in files)
                    {
                        if (file.ContentLength == 0)
                            throw new Exception("Zero length file!");                       
                        else 
                            //code for saving a file

                    }
                }
                catch (Exception)
                {
                    result = false;
                }
            }


            return new JsonResult()
                {
                    Data=result
                };


        }

    }

这是我的解决方案。

<form enctype="multipart/form-data">    

    <div class="form-group">
        <label class="control-label col-md-2" for="apta_Description">Description</label>
        <div class="col-md-10">
            <input class="form-control text-box single-line" id="apta_Description" name="apta_Description" type="text" value="">
        </div>
    </div>

    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>

和js

<script>

    $(':button').click(function () {
        var formData = new FormData($('form')[0]);
        $.ajax({
            url: '@Url.Action("Save", "Home")',  
            type: 'POST',                
            success: completeHandler,
            data: formData,
            cache: false,
            contentType: false,
            processData: false
        });
    });    

    function completeHandler() {
        alert(":)");
    }    
</script>

调节器

[HttpPost]
public ActionResult Save(string apta_Description, HttpPostedFileBase file)
{
    return Json(":)");
}

这里只是如何上传文件的另一种解决方案( 没有任何插件

使用简单的JavascriptsAJAX (带进度条)

HTML部分

<form id="upload_form" enctype="multipart/form-data" method="post">
    <input type="file" name="file1" id="file1"><br>
    <input type="button" value="Upload File" onclick="uploadFile()">
    <progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
    <h3 id="status"></h3>
    <p id="loaded_n_total"></p>
</form>

JS部分

function _(el){
    return document.getElementById(el);
}
function uploadFile(){
    var file = _("file1").files[0];
    // alert(file.name+" | "+file.size+" | "+file.type);
    var formdata = new FormData();
    formdata.append("file1", file);
    var ajax = new XMLHttpRequest();
    ajax.upload.addEventListener("progress", progressHandler, false);
    ajax.addEventListener("load", completeHandler, false);
    ajax.addEventListener("error", errorHandler, false);
    ajax.addEventListener("abort", abortHandler, false);
    ajax.open("POST", "file_upload_parser.php");
    ajax.send(formdata);
}
function progressHandler(event){
    _("loaded_n_total").innerHTML = "Uploaded "+event.loaded+" bytes of "+event.total;
    var percent = (event.loaded / event.total) * 100;
    _("progressBar").value = Math.round(percent);
    _("status").innerHTML = Math.round(percent)+"% uploaded... please wait";
}
function completeHandler(event){
    _("status").innerHTML = event.target.responseText;
    _("progressBar").value = 0;
}
function errorHandler(event){
    _("status").innerHTML = "Upload Failed";
}
function abortHandler(event){
    _("status").innerHTML = "Upload Aborted";
}

PHP部分

<?php
$fileName = $_FILES["file1"]["name"]; // The file name
$fileTmpLoc = $_FILES["file1"]["tmp_name"]; // File in the PHP tmp folder
$fileType = $_FILES["file1"]["type"]; // The type of file it is
$fileSize = $_FILES["file1"]["size"]; // File size in bytes
$fileErrorMsg = $_FILES["file1"]["error"]; // 0 for false... and 1 for true
if (!$fileTmpLoc) { // if file not chosen
    echo "ERROR: Please browse for a file before clicking the upload button.";
    exit();
}
if(move_uploaded_file($fileTmpLoc, "test_uploads/$fileName")){ // assuming the directory name 'test_uploads'
    echo "$fileName upload is complete";
} else {
    echo "move_uploaded_file function failed";
}
?>

这是EXAMPLE应用程序


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

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

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

文件上载ASP.NET Core MVC:

在html中的View create file upload control中:

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

现在在控制器中创建动作方法:

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

hostingEnvironment变量的类型为IHostingEnvironment,可以使用依赖注入将其注入控制器,如:

$('#fileupload').fileupload({
    add: function (e, data) {
        var that = this;
        $.getJSON('/example/url', function (result) {
            data.formData = result; // e.g. {id: 123}
            $.blueimp.fileupload.prototype
                .options.add.call(that, e, data);
        });
    } 
});

使用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对象的语法:

variable = new XMLHttpRequest();


跨域访问

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

这意味着网页和它尝试加载的XML文件必须位于同一台服务器上。

W3Schools上的示例都是位于W3Schools域的所有开放XML文件。

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

欲了解更多详情,您可以继续阅读here ...


您可以here看到已解决的解决方案,其中包含一个工作演示,允许您预览表单文件并将其提交给服务器。对于您的情况,您需要使用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>

提交的数据是一个表格数据。在您的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");

     });
   });
});

here


您可以使用XMLHttpRequest(没有flash和iframe依赖)在进行异步上载时传递其他参数和文件名。使用FormData附加附加参数值并发送上载请求。

function uploadButtonCLicked(){
    var input = document.querySelector('input[type="file"]')

    fetch('/url', {
      method: 'POST',
      body: input.files[0]
    }).then(res => res.json())   // you can do something with response
      .catch(error => console.error('Error:', error))
      .then(response => console.log('Success:', response));
}                               

此外,Syncfusion JavaScript UI文件上载仅使用事件参数为此方案提供解决方案。你可以找到的文档在这里和有关此控件的详细信息在这里输入链接的描述在这里


示例:如果您使用jQuery,则可以轻松上传文件。这是一个小而强大的jQuery插件,http://jquery.malsup.com/form/

var $bar   = $('.ProgressBar');
$('.Form').ajaxForm({
  dataType: 'json',

  beforeSend: function(xhr) {
    var percentVal = '0%';
    $bar.width(percentVal);
  },

  uploadProgress: function(event, position, total, percentComplete) {
    var percentVal = percentComplete + '%';
    $bar.width(percentVal)
  },

  success: function(response) {
    // Response
  }
});

我希望它会有所帮助


请在此处异步处理文件的上传过程https//developer.mozilla.org/en-US/docs/Using_files_from_web_applications

来自链接的示例

<?php
if (isset($_FILES['myFile'])) {
    // Example:
    move_uploaded_file($_FILES['myFile']['tmp_name'], "uploads/" . $_FILES['myFile']['name']);
    exit;
}
?><!DOCTYPE html>
<html>
<head>
    <title>dnd binary upload</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script type="text/javascript">
        function sendFile(file) {
            var uri = "/index.php";
            var xhr = new XMLHttpRequest();
            var fd = new FormData();

            xhr.open("POST", uri, true);
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    // Handle response.
                    alert(xhr.responseText); // handle response.
                }
            };
            fd.append('myFile', file);
            // Initiate a multipart/form-data upload
            xhr.send(fd);
        }

        window.onload = function() {
            var dropzone = document.getElementById("dropzone");
            dropzone.ondragover = dropzone.ondragenter = function(event) {
                event.stopPropagation();
                event.preventDefault();
            }

            dropzone.ondrop = function(event) {
                event.stopPropagation();
                event.preventDefault();

                var filesArray = event.dataTransfer.files;
                for (var i=0; i<filesArray.length; i++) {
                    sendFile(filesArray[i]);
                }
            }
        }
    </script>
</head>
<body>
    <div>
        <div id="dropzone" style="margin:30px; width:500px; height:300px; border:1px dotted grey;">Drag & drop your file here...</div>
    </div>
</body>
</html>






upload