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

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

我只得到文件名,而不是正在上传的文件。我能做些什么来解决这个问题?

1475098 次浏览

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


您不能使用XMLHttpRequest相关文档(Ajax)上传文件。您可以使用ifram或Flash模拟效果。通过ifram发布文件以获得效果的优秀jQuery表单插件

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

了解“新”HTML5file API的重要一点是它直到IE 10才被支持。如果您所针对的特定市场对旧版本Windows的倾向高于平均水平,您可能无法访问它。

截至2017年,大约5%的浏览器是IE 6、7、8或9之一。如果你进入一家大公司(例如,这是一个B2B工具或你正在提供培训的东西),这个数字可能会飙升。2016年,我与一家公司打交道,他们超过60%的机器使用IE8。

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

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

2008年的答案如下。


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

这是一个“真实”的帖子,所以它不完全是交互式的。如果你需要状态,你需要一些服务器端的东西来处理它。这取决于你的服务器。ASP.NET有更好的机制。PHP普通失败,但你可以使用perl或Apache修改来解决它。

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

或者使用Java /Flash的解决方案。他们在处理帖子方面更加灵活…

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

我建议为此目的使用精细上传器插件。您的JavaScript代码将是:

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

我在Rails环境下写的。如果您使用轻量级的jQuery-form插件,它只有大约五行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.saverender :text => @image.public_filename

在过去的几周里,我一直在使用Bloggity,它的工作方式就像一个冠军。

这个AJAX文件上传jQuery插件上传文件,并传递#36825;,没有别的了

  • 它不依赖于特定的超文本标记语言,只需给它一个<input type="file">
  • 它不需要您的服务器以任何特定方式响应
  • 无论您使用多少文件或它们在页面上的位置

--尽量少用--

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

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

超文本标记语言:

<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 uploadurl: 'upload.php',type: 'POST',
// Form datadata: 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 XMLHttpRequestxhr: function () {var myXhr = $.ajaxSettings.xhr();if (myXhr.upload) {// For handling the progress of the uploadmyXhr.upload.addEventListener('progress', function (e) {if (e.lengthComputable) {$('progress').attr({value: e.loaded,max: e.total,});}}, false);}return myXhr;}});});

如您所见,使用HTML5(和一些研究)文件上传不仅成为可能,而且非常容易。使用GoogleChrome尝试一下,因为示例的一些HTML5组件并非在每个浏览器中都可用。

我一直在使用下面的脚本上传图像,碰巧工作正常。

超文本标记语言

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

补充说明

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

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

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

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

您可以很容易地用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 alongxhr.send(file);

jQuery上传是我以前用来上传文件的另一个很好的插件。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);}

简单的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 buttonurl: '/uploadhandler', // URL of server-side upload handlername: 'userfile', // parameter name of the uploaded fileonSubmit: function() {this.setProgressBar( $('#progressBar') ); // designate elem as our progress bar},onComplete: function(file, response) {// do whatever after upload is finished}});

您可以使用

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

演示

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

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

步骤2在超文本标记语言文件中添加以下脚本,这些文件已经通过运行上述包添加到项目中:

jquery.ui.widget.js

jquery.iframe-transport.js

jquery.fileupload.js

步骤3按照下面的代码编写文件上传控件:

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

步骤4编写一个js方法作为上传文件,如下所示:

 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 controllerdata.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};

}
}

使用|HTML5的ReadAsDataURL()获取数据的方式一些base 64编码器将文件转换为base 64。在这里摆弄

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

我过去做过的最简单、最健壮的方法就是简单地用你的表单定位一个隐藏的iFrame标签——然后它将在iframe中提交,而无需重新加载页面。

也就是说,如果您不想使用插件、JavaScript或超文本标记语言以外的任何其他形式的“魔法”。当然,您可以将其与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>

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

Chrome、iFrames和onLoad

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

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

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

要做到这一点,基本上是在上传/下载开始时:

  • 【客户端】开始一个间隔,查找是否存在cookie
  • 【服务端】对文件数据做任何你需要做的事情
  • [服务器端]为客户端间隔设置cookie
  • [客户端]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回调。

您可以使用jQuery.ajax()简单地上传。

超文本标记语言:

<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) {// ...}});}));});

为未来的读者做好准备。

异步文件上传

使用HTML5

如果支持表单数据文件API(均为HTML5功能),则可以使用$.ajax()方法上传文件与jQuery

您也可以发送文件没有表单数据,但无论哪种方式,文件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(没有文件API)时,唯一的纯JavaScript解决方案(没有Flash或任何其他浏览器插件)是隐藏ifram技术,它允许在不使用XMLHttpRequest相关文档对象的情况下模拟异步请求。

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

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

在这种情况下,您可能更喜欢使用像Bifröst这样的包装插件,它使用ifram技术,但也提供了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表单插件jQuery文件上传,包括从HTML5到不同回退的整个堆栈和一些有用的功能,以简化流程。根据您的需求和要求,您可能需要考虑裸实现或此插件中的任何一个。

在这里查找异步处理文件的上载过程https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications

链接中的样本

<?phpif (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 uploadxhr.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>
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){ }});

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

这是我的解决方案。

<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){[...]}

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

使用简单的javascriptAJAX(带有进度条)

超文本标记语言部分

<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 trueif (!$fileTmpLoc) { // if file not chosenecho "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";}?>

这是示例应用程序

您可以通过工作演示<强>这里看到已解决的解决方案,该演示允许您预览表单文件并将其提交到服务器。对于您的情况,您需要使用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");
});});});

查看更多详细信息

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

我希望这会有帮助

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

你试过jQuery文件上传吗?

以下是上面链接中的一个示例,可以解决您的问题:

$('#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,上传async很容易,我创建上传逻辑以及您的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文件,必须位于同一服务器上。

W3学校上的示例都打开了位于W3学校上的XML文件域名。

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

有关更多详细信息,您可以继续阅读这里

您可以通过JavaScript使用新的获取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在所有现代浏览器中都是原生支持,因此您无需导入任何内容。此外,请注意,get()返回Promise,然后通过异步使用.then(..code to handle response..)进行处理。

一种现代方法没有jQuery是在用户选择文件时使用从<input type="file">返回的文件列表对象,然后使用拿过来发布包裹在表单数据对象周围的FileList。

// The input DOM element // <input type="file">const inputElement = document.querySelector('input[type=file]');
// Listen for a file submit from userinputElement.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  bodyfetch('/uploadImage', {method: 'POST',body: data});});

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

  1. ASP.NET基于Web表单的带有进度条的多重文件上传功能
  2. ASP.NETjQuery中基于MVC的多文件上传

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

文件上传ASP.NET核心MVC:

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

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

现在在控制器中创建action方法:

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

主机环境变量是IHostingEnvironment类型,可以使用依赖注入注入到控制器中,例如:

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

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

超文本标记语言

<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 submissionevent.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 imagepreviewImage.removeAttribute("src");// show uploading textuploadingText.style.display = "block";// create form data and append the filevar formData = new FormData();formData.append("image", file);// do the ajax partvar 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 errorif ($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 existsif (!file_exists($image['tmp_name']))throw new Exception('Image file is missing in the server');$maxFileSize = 2 * 10e6; // in bytesif ($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)));} elsethrow new Exception('Error in saving into the database');
} catch (Exception $e) {exit(json_encode(array ('status' => false,'error' => $e -> getMessage())));}

您可以在使用XMLHttpRequest进行异步上传时传递附加参数和文件名(没有flash和ifram依赖项)。使用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文件上传为这个场景提供了解决方案,只需使用事件参数即可。您可以找到留档这里和有关此控件的更多详细信息,请在此处输入链接描述这里

你也可以考虑使用类似于https://uppy.io的东西。

它在不离开页面的情况下进行文件上传,并提供一些奖励,如拖放,在浏览器崩溃/片状网络的情况下恢复上传,以及从例如Instagram导入。它是开源的,不依赖于jQuery/React/Angular/Vue,但可以与之一起使用。免责声明:作为它的创建者,我有偏见;)

您可以使用以下代码。

async: false(true)

试试看

async function saveFile(){let formData = new FormData();formData.append("file", file.files[0]);await fetch('addFile.do', {method: "POST", body: formData});alert("Data Uploaded: ");}
<span>File</span><input type="file" id="file" name="file" size="10"/><input type="button" value="Upload" onclick="saveFile()"/>

content-type='multipart/form-data'由浏览器自动设置,文件名也自动添加到filename FormData参数中(并且可以很容易地由服务器读取)。这是一个更发达的示例,带有错误处理和json添加

async function saveFile(inp){let user = { name:'john', age:34 };let formData = new FormData();let photo = inp.files[0];         
formData.append("photo", photo);formData.append("user", JSON.stringify(user));    
try {let r = await fetch('/upload/image', {method: "POST", body: formData});console.log('HTTP response code:',r.status);alert('success');} catch(e) {console.log('Huston we have problem...:', e);}    
}
<input type="file" onchange="saveFile(this)" ><br><br>Before selecting the file Open chrome console > network tab to see the request details.<br><br><small>Because in this example we send request to https://stacksnippets.net/upload/image the response code will be 404 ofcourse...</small>

如果使用Promise哪个ajax并检查文件是否有效并保存在您的后端会怎样,那么您可以在用户浏览页面时在前面使用一些动画。

您甚至可以使用递归方法使其并行上传或堆叠