如何使用 jQuery 异步上传文件?

Posted

技术标签:

【中文标题】如何使用 jQuery 异步上传文件?【英文标题】:How can I upload files asynchronously with jQuery? 【发布时间】:2021-09-16 14:17:22 【问题描述】:

我想用 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"/>

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

【问题讨论】:

有各种现成的 jQuery 文件上传插件。进行这种上传技巧并不是一种愉快的体验,因此人们喜欢使用现成的解决方案。这里有几个: - JQuery File Uploader - Multiple File Upload Plugin - Mini Multiple File Upload - jQuery File Upload 您可以在 NPM(使用“jquery-plugin”作为关键字)或 Github 上搜索更多项目。 你只得到文件名,因为你的 var 文件名得到 $('#file') 的值,而不是输入中的文件 这是一个不错的选择:http://blueimp.github.io/jQuery-File-Upload/ - html5 ajax 上传 - 为不受支持的浏览器优雅地回退到 iframe - 多文件异步上传 我们已经使用它并且效果很好。 (Documentation here) 检查这个:***.com/questions/6974684/…,这里解释了如何通过 jQuery 实现它 @Jimmy 他将如何获取输入中的文件? 【参考方案1】:

使用HTML5,您可以使用 Ajax 和 jQuery 进行文件上传。不仅如此,您还可以进行文件验证(名称、大小和 MIME 类型)或使用 HTML5 进度标签(或 div)处理进度事件。最近我不得不做一个文件上传器,但我不想使用Flash 也不想使用 iframe 或插件,经过一些研究我想出了解决方案。

HTML:

<form enctype="multipart/form-data">
    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>
<progress></progress>

首先,您可以根据需要进行一些验证。比如在文件的.on('change')事件中:

$(':file').on('change', function () 
  var file = this.files[0];

  if (file.size > 1024) 
    alert('max upload size is 1k');
  

  // Also see .name, .type
);

现在$.ajax() 通过单击按钮提交:

$(':button').on('click', function () 
  $.ajax(
    // Your server script to process the upload
    url: 'upload.php',
    type: 'POST',

    // Form data
    data: new FormData($('form')[0]),

    // Tell jQuery not to process data or worry about content-type
    // You *must* include these options!
    cache: false,
    contentType: false,
    processData: false,

    // Custom XMLHttpRequest
    xhr: function () 
      var myXhr = $.ajaxSettings.xhr();
      if (myXhr.upload) 
        // For handling the progress of the upload
        myXhr.upload.addEventListener('progress', function (e) 
          if (e.lengthComputable) 
            $('progress').attr(
              value: e.loaded,
              max: e.total,
            );
          
        , false);
      
      return myXhr;
    
  );
);

如您所见,通过 HTML5(和一些研究)文件上传不仅变得可能而且超级简单。尝试使用 Google Chrome,因为示例的某些 HTML5 组件并非在每个浏览器中都可用。

【讨论】:

我的文件部分正在工作...但是您也可以在其中包含文本字段吗?这似乎与 var formData = new FormData($('form')[0]);serialize() 无关? 我可以在upload.php中使用$_FILES吗? 这应该可以在 Internet Explorer 中使用,但只能在版本 10 中使用。(caniuse.com/xhr2) 您好,我很欣赏 PHP 是您选择的语言...但我想知道您是否知道这是否也适用于 ASP.NET MVC?我是一名 .NET 开发人员,我尝试利用您的简单示例进行一些 AJAX 文件上传,但服务器端我没有获得通过 AJAX 发布的文件。我正在使用最新的 Chrome。 FormData 在这里施展了所有魔法。请务必查看这些文档——它涵盖了您关于多个文件和字段的所有问题。【参考方案2】:

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

理解“新”HTML5 file API 的重要一点是它 wasn't supported until IE 10。如果您瞄准的特定市场对旧版 Windows 的倾向高于平均水平,您可能无法访问它。

截至 2017 年,大约 5% 的浏览器是 IE 6、7、8 或 9 之一。如果您进入一家大公司(例如,这是一个 B2B 工具或您为培训提供的东西),这个数字可以暴涨。 2016 年,我与一家公司打交道,他们 60% 以上的机器都使用 IE8。

截至本次编辑是 2019 年,距离我最初的回答已经过去了将近 11 年。 IE9 及更低版本全球在 1% 左右,但仍有较高使用率的集群。

重要的收获——无论是什么功能——是,检查您的用户使用什么浏览器。如果你不这样做,你会很快学到一个痛苦的教训,为什么“为我工作”在交付给客户时不够好。 caniuse 是一个有用的工具,但请注意他们从哪里获得人口统计数据。它们可能与您的不一致。这比企业环境更真实。

下面是我 2008 年的回答。


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

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

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

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

【讨论】:

如果浏览器支持文件 API,现在可以进行纯 AJAX 文件上传 - developer.mozilla.org/en/using_files_from_web_applications 这是一个相当老的答案,但它有点误导.. IE 早在 IE7 就原生支持 XHR,而早在 IE5 就通过 ActiveX 支持它。 w3schools.com/ajax/ajax_xmlhttprequest_create.asp。执行此操作的实际方法当然是针对 Flash(冲击波)组件,或推出 Flash/ActiveX (Silverlight) 控件。如果您可以通过 javascript 发起请求并处理响应,那么它就是 ajax。尽管如此,ajax 是 xhr 的同义词,但它本身并没有描述传递/交换有效负载的下划线机制/组件。跨度> @BrettCaswell 我并不是说 AJAX/XHR 是不可能的,只是不可能在旧的——但永存的——版本的 IE 上发布文件。这曾经是并且仍然是完全正确的。【参考方案3】:

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

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

【讨论】:

"此插件在 GNU GPL 2 或更高版本和 GNU LGPL 2 或更高版本下开源。"因此,只要您不分发副本或修改版本,您就不必打开您的项目。 万一有人尝试走这条路,FineUploader 已于 2018 年停产。github.com/FineUploader/fine-uploader/issues/2073【参考方案4】:

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


您无法使用XMLHttpRequest (Ajax) 上传文件。您可以使用 iframe 或 Flash 模拟效果。出色的jQuery Form Plugin,通过 iframe 发布您的文件以获得效果。

【讨论】:

小备注:在chrome和firefox的最新版本中是可以的,***.com/questions/4856917/…【参考方案5】:

为未来的读者总结。

异步文件上传

使用 HTML5

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

您也可以发送文件without FormData,但无论哪种方式,文件 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)示例,请参阅“Sending files using a FormData object”。

后备

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

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

如果处理得当,它几乎可以在任何浏览器上运行,但它有一些关于如何从 iframe 获取响应的警告。

在这种情况下,您可能更喜欢使用像 Bifröst 这样的包装插件,它使用 iframe 技术,但也提供了 jQuery Ajax transport 允许 发送文件 $.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 到不同回退的整个堆栈和一些有用的功能来缓解过程。根据您的需要和要求,您可能需要考虑裸实现或其中任何一个插件。

【讨论】:

【参考方案6】:

这个AJAX file upload jQuery plugin 在某个地方上传文件,并通过 响应回调,仅此而已。

它不依赖于特定的HTML,只需给它一个&lt;input type="file"&gt; 它不需要您的服务器以任何特定方式响应 无论您使用了多少文件,也不管它们在页面上的什么位置

-- 尽量少用--

$('#one-specific-file').ajaxfileupload(
  'action': '/upload.php'
);

-- 或尽可能多--

$('input[type="file"]').ajaxfileupload(
  'action': '/upload.php',
  'params': 
    'extra': 'info'
  ,
  'onComplete': function(response) 
    console.log('custom handler for file:');
    alert(JSON.stringify(response));
  ,
  'onStart': function() 
    if(weWantedTo) return false; // cancels upload
  ,
  'onCancel': function() 
    console.log('no file selected');
  
);

【讨论】:

【参考方案7】:

我一直在使用下面的脚本来上传图片,它恰好可以正常工作。

HTML

<input id="file" type="file" name="file"/>
<div id="response"></div>

JavaScript

jQuery('document').ready(function()
    var input = document.getElementById("file");
    var formdata = false;
    if (window.FormData) 
        formdata = new FormData();
    
    input.addEventListener("change", function (evt) 
        var i = 0, len = this.files.length, img, reader, file;

        for ( ; i < len; i++ ) 
            file = this.files[i];

            if (!!file.type.match(/image.*/)) 
                if ( window.FileReader ) 
                    reader = new FileReader();
                    reader.onloadend = function (e) 
                        //showUploadedItem(e.target.result, file.fileName);
                    ;
                    reader.readAsDataURL(file);
                

                if (formdata) 
                    formdata.append("image", file);
                    formdata.append("extra",'extra-data');
                

                if (formdata) 
                    jQuery('div#response').html('<br /><img src="ajax-loader.gif"/>');

                    jQuery.ajax(
                        url: "upload.php",
                        type: "POST",
                        data: formdata,
                        processData: false,
                        contentType: false,
                        success: function (res) 
                         jQuery('div#response').html("Successfully uploaded");
                        
                    );
                
            
            else
            
                alert('Not a vaild image!');
            
        

    , false);
);

说明

我使用 response div 来显示上传动画和上传完成后的响应。

最好的部分是您可以在使用此脚本时随文件发送额外的数据,例如 ids 等。我在脚本中提到了extra-data

在 PHP 级别,这将像正常的文件上传一样工作。额外数据可以检索为$_POST 数据。

在这里你没有使用插件和东西。您可以根据需要更改代码。您不是在这里盲目编码。这是任何 jQuery 文件上传的核心功能。实际上是 Javascript。

【讨论】:

【参考方案8】:

你可以很容易地在原生 JavaScript 中做到这一点。这是我当前项目中的一个 sn-p:

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

【讨论】:

【参考方案9】:

您可以简单地使用 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) 
                // ...
            
       );
    ));
);

【讨论】:

【参考方案10】:

我过去做过的最简单和最可靠的方法是简单地将隐藏的 iFrame 标记与您的表单一起定位 - 然后它将在 iframe 内提交而无需重新加载页面。

也就是说,如果您不想使用插件、JavaScript 或 HTML 以外的任何其他形式的“魔法”。当然你可以把它和 JavaScript 或者你有的东西结合起来......

<form target="iframe" action="" method="post" enctype="multipart/form-data">
    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>

<iframe name="iframe" id="iframe" style="display:none" ></iframe>

您还可以读取 iframe onLoad 的内容以获取服务器错误或成功响应,然后将其输出给用户。

Chrome、iFrames 和 onLoad

-注意-如果您对如何在上传/下载时设置 UI 拦截器感兴趣,您只需继续阅读

目前,Chrome 在用于传输文件时不会触发 iframe 的 onLoad 事件。 Firefox、IE 和 Edge 都会触发文件传输的 onload 事件。

我发现适用于 Chrome 的唯一解决方案是使用 cookie。

基本上在开始上传/下载时这样做:

[Client Side] 启动间隔以查找 cookie 的存在 [服务器端] 对文件数据做任何你需要的事情 [服务器端] 为客户端间隔设置 cookie [Client Side] Interval 看到 cookie 并像 onLoad 事件一样使用它。例如,您可以启动一个 UI 拦截器,然后在 onLoad(或在制作 cookie 时)删除该 UI 拦截器。

为此使用 cookie 很难看,但它确实有效。

我做了一个jQuery插件来处理Chrome下载时的这个问题,你可以在这里找到

https://github.com/ArtisticPhoenix/jQuery-Plugins/blob/master/iDownloader.js

同样的基本原则也适用于上传。

要使用下载器(当然包括 JS)

 $('body').iDownloader(
     "onComplete" : function()
          $('#uiBlocker').css('display', 'none'); //hide ui blocker on complete
     
 );

 $('somebuttion').click( function()
      $('#uiBlocker').css('display', 'block'); //block the UI
      $('body').iDownloader('download', 'htttp://example.com/location/of/download');
 );

在服务器端,在传输文件数据之前,创建 cookie

 setcookie('iDownloader', true, time() + 30, "/");

插件会看到cookie,然后触发onComplete回调。

【讨论】:

【参考方案11】:

I've written this up in a Rails environment。如果你使用轻量级的 jQuery-form 插件,它只有大约 5 行 JavaScript。

挑战在于让 AJAX 上传工作,因为标准 remote_form_for 不理解多部分表单提交。它不会发送 Rails 通过 AJAX 请求返回的文件数据。

这就是 jQuery-form 插件发挥作用的地方。

这是它的 Rails 代码:

<% remote_form_for(:image_form, 
                   :url =>  :controller => "blogs", :action => :create_asset , 
                   :html =>  :method => :post, 
                              :id => 'uploadForm', :multipart => true ) 
                                                                        do |f| %>
 Upload a file: <%= f.file_field :uploaded_data %>
<% end %>

以下是相关的 JavaScript:

$('#uploadForm input').change(function()
 $(this).parent().ajaxSubmit(
  beforeSubmit: function(a,f,o) 
   o.dataType = 'json';
  ,
  complete: function(XMLHttpRequest, textStatus) 
   // XMLHttpRequest.responseText will contain the URL of the uploaded image.
   // Put it in an image element you create, or do with it what you will.
   // For example, if you have an image elemtn with id "my_image", then
   //  $('#my_image').attr('src', XMLHttpRequest.responseText);
   // Will set that image tag to display the uploaded image.
  ,
 );
);

这里是 Rails 控制器动作,非常普通:

 @image = Image.new(params[:image_form])
 @image.save
 render :text => @image.public_filename

过去几周我在 Bloggity 上一直在使用它,效果非常好。

【讨论】:

【参考方案12】:

Simple Ajax Uploader 是另一种选择:

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

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

示例用法:

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

【讨论】:

【参考方案13】:

我找到的一个解决方案是让&lt;form&gt; 定位一个隐藏的 iFrame。然后 iFrame 可以运行 JS 向用户显示它已完成(在页面加载时)。

【讨论】:

【参考方案14】:

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

使用简单的 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";

?>

Here's the EXAMPLE application

【讨论】:

【参考方案15】:

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

【讨论】:

【参考方案16】:
var formData=new FormData();
formData.append("fieldname","value");
formData.append("image",$('[name="filename"]')[0].files[0]);

$.ajax(
    url:"page.php",
    data:formData,
    type: 'POST',
    dataType:"JSON",
    cache: false,
    contentType: false,
    processData: false,
    success:function(data) 
);

您可以使用表单数据发布您的所有值,包括图片。

【讨论】:

【参考方案17】:

没有 Jquery 的现代方法是在用户选择文件时使用从 &lt;input type="file"&gt; 返回的 FileList 对象,然后使用 Fetch 发布包裹的 FileList FormData 对象。

// The input DOM element // <input type="file">
const inputElement = document.querySelector('input[type=file]');

// Listen for a file submit from user
inputElement.addEventListener('change', () => 
    const data = new FormData();
    data.append('file', inputElement.files[0]);
    data.append('imageName', 'flower');

    // You can then post it to your server.
    // Fetch can accept an object of type FormData on its  body
    fetch('/uploadImage', 
        method: 'POST',
        body: data
    );
);

【讨论】:

【参考方案18】:

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

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

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

jquery.ui.widget.js

jquery.iframe-transport.js

jquery.fileupload.js

第三步 如下代码编写文件上传控件:

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

第四步写一个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 在准备好的函数调用元素文件上传以启动如下流程:

$(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
                ;


        

    

【讨论】:

【参考方案19】:

您可以通过工作演示 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>

提交的数据是一个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");

     );
   );
);

View more details

【讨论】:

【参考方案20】:

示例:如果您使用 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
  
);

希望对您有所帮助

【讨论】:

【参考方案21】:

你可以使用

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

Demo

【讨论】:

【参考方案22】:

使用 |HTML5 的 readAsDataURL() 或 some base64 encoder 将文件转换为 base64。 Fiddle here

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

【讨论】:

【参考方案23】:

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


var formData = new FormData();
formData.append('parameter1', 'value1');
formData.append('parameter2', 'value2'); 
formData.append('file', $('input[type=file]')[0].files[0]);

$.ajax(
    url: 'post back url',
    data: formData,
// other attributes of AJAX
);

此外,Syncfusion JavaScript UI 文件上传为这种场景提供了解决方案,只需使用事件参数。您可以在此处找到文档here 以及有关此控件的更多详细信息,请输入链接描述here

【讨论】:

【参考方案24】:

这是我的解决方案。

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

    [...]

【讨论】:

您似乎在您的答案中混入了某种框架。您至少应该提及您的答案可用于哪个框架。更好的是,删除所有框架内容,只提供所提出问题的答案。 那么实际上有一个名为“mvc”的mvc框架?它使用 csharpish 语法?太残忍了。【参考方案25】:

在此处查找异步处理文件的上传过程: 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>

【讨论】:

【参考方案26】:

您可以通过 JavaScript 使用 较新 Fetch API。像这样:

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

优势:所有现代浏览器都原生支持 Fetch API,因此您无需导入任何内容。另外,请注意 fetch() 返回一个 Promise,然后使用 .then(..code to handle response..) 异步处理。

【讨论】:

【参考方案27】:

使用 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 文件必须位于您自己的服务器上。

更多详情可以继续阅读here...

【讨论】:

【参考方案28】:

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

    ASP.NET Web Forms based Mulitple File Upload Feature with Progress Bar ASP.NET MVC based Multiple File Upload made in jQuery

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

文件上传 ASP.NET Core MVC:

在 html 中的 View 创建文件上传控件:

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

【讨论】:

【参考方案29】:

对于 PHP,请查找 https://developer.hyvor.com/php/image-upload-ajax-php-mysql

HTML

<html>
<head>
    <title>Image Upload with AJAX, PHP and MYSQL</title>
</head>
<body>
<form onsubmit="submitForm(event);">
    <input type="file" name="image" id="image-selecter" accept="image/*">
    <input type="submit" name="submit" value="Upload Image">
</form>
<div id="uploading-text" style="display:none;">Uploading...</div>
<img id="preview">
</body>
</html>

JAVASCRIPT

var previewImage = document.getElementById("preview"),  
    uploadingText = document.getElementById("uploading-text");

function submitForm(event) 
    // prevent default form submission
    event.preventDefault();
    uploadImage();


function uploadImage() 
    var imageSelecter = document.getElementById("image-selecter"),
        file = imageSelecter.files[0];
    if (!file) 
        return alert("Please select a file");
    // clear the previous image
    previewImage.removeAttribute("src");
    // show uploading text
    uploadingText.style.display = "block";
    // create form data and append the file
    var formData = new FormData();
    formData.append("image", file);
    // do the ajax part
    var ajax = new XMLHttpRequest();
    ajax.onreadystatechange = function() 
        if (this.readyState === 4 && this.status === 200) 
            var json = JSON.parse(this.responseText);
            if (!json || json.status !== true) 
                return uploadError(json.error);

            showImage(json.url);
        
    
    ajax.open("POST", "upload.php", true);
    ajax.send(formData); // send the form data

PHP

<?php
$host = 'localhost';
$user = 'user';
$password = 'password';
$database = 'database';
$mysqli = new mysqli($host, $user, $password, $database);


 try 
    if (empty($_FILES['image'])) 
        throw new Exception('Image file is missing');
    
    $image = $_FILES['image'];
    // check INI error
    if ($image['error'] !== 0) 
        if ($image['error'] === 1) 
            throw new Exception('Max upload size exceeded');

        throw new Exception('Image uploading error: INI Error');
    
    // check if the file exists
    if (!file_exists($image['tmp_name']))
        throw new Exception('Image file is missing in the server');
    $maxFileSize = 2 * 10e6; // in bytes
    if ($image['size'] > $maxFileSize)
        throw new Exception('Max size limit exceeded'); 
    // check if uploaded file is an image
    $imageData = getimagesize($image['tmp_name']);
    if (!$imageData) 
        throw new Exception('Invalid image');
    $mimeType = $imageData['mime'];
    // validate mime type
    $allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif'];
    if (!in_array($mimeType, $allowedMimeTypes)) 
        throw new Exception('Only JPEG, PNG and GIFs are allowed');

    // nice! it's a valid image
    // get file extension (ex: jpg, png) not (.jpg)
    $fileExtention = strtolower(pathinfo($image['name'] ,PATHINFO_EXTENSION));
    // create random name for your image
    $fileName = round(microtime(true)) . mt_rand() . '.' . $fileExtention; // anyfilename.jpg
    // Create the path starting from DOCUMENT ROOT of your website
    $path = '/examples/image-upload/images/' . $fileName;
    // file path in the computer - where to save it 
    $destination = $_SERVER['DOCUMENT_ROOT'] . $path;

    if (!move_uploaded_file($image['tmp_name'], $destination))
        throw new Exception('Error in moving the uploaded file');

    // create the url
    $protocol = stripos($_SERVER['SERVER_PROTOCOL'],'https') === true ? 'https://' : 'http://';
    $domain = $protocol . $_SERVER['SERVER_NAME'];
    $url = $domain . $path;
    $stmt = $mysqli -> prepare('INSERT INTO image_uploads (url) VALUES (?)');
    if (
        $stmt &&
        $stmt -> bind_param('s', $url) &&
        $stmt -> execute()
    ) 
        exit(
            json_encode(
                array(
                    'status' => true,
                    'url' => $url
                )
            )
        );
     else 
        throw new Exception('Error in saving into the database');

 catch (Exception $e) 
    exit(json_encode(
        array (
            'status' => false,
            'error' => $e -> getMessage()
        )
    ));

【讨论】:

【参考方案30】:

这是一个老问题,但仍然没有答案正确答案,所以:

你试过jQuery-File-Upload吗?

这是来自上面链接的一个示例,它可能会解决您的问题:

$('#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);
        );
     
);

【讨论】:

以上是关于如何使用 jQuery 异步上传文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 jQuery 异步上传文件?

如何使用 jQuery 异步上传文件?

异步 JQUERY 文件上传

Jquery FormData文件异步上传 快速指南

jquery-uploadfile的使用(多文件异步上传)

使用 jQuery 和 ASP.NET MVC 异步上传文件,无需表单提交和异步