記錄小文件上傳的幾個例子(含進度條效果,附源碼下載)
阿新 • • 發佈:2018-10-29
clas 運行 open ntb httppost 會有 text recent mappath
1、簡單原生上傳
- 無javascript腳本、無進度條;
- 借助iframe實現post提交後的無刷新效果;
- jquery插件ajaxFileUpload.js的實現原型。
Html代碼
<form enctype="multipart/form-data" action="UploadFile_1" method="post" target="frameResult"> <div class="item"> <input id="File1" name="UserPhoto" type="file"value="" /> <input type="submit" value="提交上傳" /> <iframe src="about:blank" id="frameResult" name="frameResult"></iframe> </div> </form>
後臺代碼(ASP.NET MVC)
[HttpPost] public ActionResult UploadFile_1() {string result = "上傳成功"; HttpPostedFileBase file= Request.Files["UserPhoto"]; file.SaveAs(Server.MapPath("~/Upload/")+ file.FileName); return Content(result); }
要點說明
- 為<form>標簽的action、method設值,以POST方式請求UploadFile_1方法;
- 為<form>標簽的enctype屬性設值multipart/form-data,讓POST請求帶上<input type="file">的文件內容;
- 為<form>標簽的target屬性設值frameResult,讓表單的請求響應結果放到名為frameResult的iframe中顯示。
2、純JavaScript異步上傳
- 借助HTML5特性實現進度條、上傳速度計算;
- 無需<form>標簽;
- 不支持IE8、IE9等低版本瀏覽器。
JavaScript代碼,因為不需要<form>標簽,html也沒什麽內容可貼的了。
var btnUpload = document.getElementById(‘btnUpload‘); btnUpload.onclick = function () { var fileInput = document.getElementById(‘File2‘); if (!fileInput.value) { return; } var feature = {}; feature.fileapi = fileInput.files !== undefined; feature.formdata = (typeof window.FormData !== ‘undefined‘); if (!feature.fileapi || !feature.formdata) { showMessage(‘當前瀏覽器不支持Html5,請更換高級瀏覽器‘); return; } var xhr = new XMLHttpRequest(); var formData = new FormData(); formData.append("UserPhoto", fileInput.files[0]); xhr.open("post", ‘./UploadFile_2‘); //超時時間,單位是毫秒 xhr.timeout = 60 * 1000; //請求結束 xhr.onload = function (event) { if (xhr.status == 200) { showMessage("上傳成功"); return; } if (xhr.status == 404) { showMessage("請求路徑錯誤"); setProgressBar(0, ‘kb/s‘, ‘hide‘, ‘0%‘); return; } if (xhr.status == 500) { console.error(‘xhr.status == 500‘); showMessage("服務器異常"); } }; //請求異常(不包括404) xhr.onerror = function () { console.error(‘xhr.onerror‘); showMessage("請求發生異常"); }; //上傳開始事件 xhr.upload.onloadstart = function () { setProgressBar(0, ‘kb/s‘, ‘hide‘, ‘0%‘); lastTime = new Date().getTime(); loadSize = 0; } //上傳過程事件,間歇調用該方法用來獲取上傳過程中的信息 xhr.upload.onprogress = function (event) { //ProgressEvent.lengthComputable:boolean類型,表示能否計算出文件長度;如果為false,那麽ProgressEvent.total則為0. //簡而言之,lengthComputabl等於true就可以做進度計算 if (!event.lengthComputable) { return; } //計算上傳速度,event.loaded是已發送的大小 var now = new Date().getTime(); var timeInterval = (now - lastTime) / 1000; lastTime = now; var sizeInterval = event.loaded - loadSize; loadSize = event.loaded; var speed = sizeInterval / timeInterval; // 單位b/s var bspeed = speed; var units = "b/s"; if (speed / 1024 > 1) { speed = speed / 1024; units = ‘kb/s‘; } if (speed / 1024 > 1) { speed = speed / 1024; units = ‘mb/s‘; } speed = speed.toFixed(1); //計算剩余時間 var resttime = ((event.total - event.loaded) / bspeed).toFixed(1); //單位 秒 //計算進度百分比 var precent = (100 * event.loaded / event.total); pre = Math.floor(precent); if (bspeed == 0) { //setProgressBar方法是控制進度條的, //這裏代碼沒貼,在最後源碼下載裏有 //四個參數:上傳速度、單位、剩余時間、進度百分比 setProgressBar(0, "b/s", ‘infinity‘, ‘noChange‘); } else { setProgressBar(speed, units, resttime, precent + ‘%‘); } }; //上傳終止 xhr.upload.onabort = function () { console.info(‘xhr.upload.onabort‘); } //上傳異常事件 //當網絡環境正常時,XMLHttpRequest.status等於404、500並不能觸發upload.onerror事件 //當網絡環境異常時(offline),會觸發upload.onerror事件 xhr.upload.onerror = function () { console.error(‘xhr.upload.onerror‘); } //文件發送完畢事件 //當網絡環境正常時,即使XMLHttpRequest.status等於404、500,仍會被觸發upload.onload事件 //當網絡環境異常時(offline),不會觸發upload.onload事件 xhr.upload.onload = function () { console.info(‘xhr.upload.onload‘); } //上傳超時 xhr.upload.ontimeout = function () { console.error(‘xhr.upload.ontimeout‘); } //發送請求 xhr.send(formData); }
後臺接收代碼
[HttpPost] public ActionResult UploadFile_2() { HttpPostedFileBase file = Request.Files["UserPhoto"]; file.SaveAs(Server.MapPath("~/Upload/") + file.FileName); return Json("success"); }
要點說明
- 無需 <form> 標簽
- 通過判斷document.getElementById(‘File2‘).files 及 window.FormData 對象是否為 undefined ,得出當前瀏覽器是否具備我們所需的HTML5特性;
- FormData對象如同其名稱一樣以鍵值對形式存儲表單數據;
- 主要借助 xhr.upload 對象的兩個事件 onloadstart、onprogress 實現進度條。
3、JQuery異步上傳
- 上個例子的Jquery版;
- 同樣需要HTML5特性支持,無法在低版本瀏覽器使用。
$(‘#btnUpload3‘).click(function () { var $fileInput = $(‘#File3‘); if (!$fileInput.val()) { return; } var feature = {}; //檢查是否支持html5 api feature.fileapi = $fileInput.get(0).files !== undefined; feature.formdata = (typeof window.FormData !== ‘undefined‘); if (!feature.fileapi || !feature.formdata) { showMessage(‘當前瀏覽器不支持Html5,請更換高級瀏覽器‘); return; } var formData = new FormData(); formData.append("UserPhoto", $fileInput[0].files[0]); $.ajax({ type: ‘post‘, url: ‘./UploadFile_2‘, data: formData, processData: false,//設置為false。因為data值是FormData對象,不需要對數據做處理。 contentType: false, //設置為false。告訴jQuery不要去設置Content-Type請求頭 xhr: function () { var xhr = $.ajaxSettings.xhr(); if (xhr.upload) { xhr.upload.onloadstart = uploadStart; xhr.upload.onprogress = uploadProgress; return xhr; } }, success: function (data, textStatus, jqXHR) { showMessage("上傳成功"); }, error: function (jqXHR, textStatus, errorThrown) { showMessage("上傳失敗"); } }); });
要點說明
- processData、contentType 設置為 false;
- $.ajax()方法中需要為請求設置xhr賦值一個function,用於加工$.ajax()的XmlHttpRequest對象,為xhr.upload 對象的兩個事件 onloadstart、onprogress 綁定處理方法,處理方法同例子2一樣。最後的源碼下載中會有。
4、異步表單插件jquery.form.js
- 前三個例子的集成版,需要 <form> 標簽做兼容;
- 當瀏覽器不支持H5,使用例子1的方式;
- 當瀏覽器支持H5,使用例子2、3的方式。
html代碼
<form id="form4" enctype="multipart/form-data" action="UploadFile_2" method="post"> <div class="item"> <h3> 4、異步表單插件jquery.form.js </h3> <input id="File4" name="UserPhoto" type="file" value="" /> <input id="btnUpload4" type="button" value="提交上傳" /> </div> </form>
js代碼
$(‘#btnUpload4‘).click(function () { var $fileInput = $(‘#File4‘); if (!$fileInput.val()) { return; } var options = { type: ‘post‘, url: ‘./UploadFile_2‘, success: function (data, textStatus, jqXHR) { showMessage("上傳成功"); }, error: function (jqXHR, textStatus, errorThrown) { showMessage("上傳失敗"); } } var feature = {}; //檢查是否支持html5 api feature.fileapi = $fileInput.get(0).files !== undefined; feature.formdata = (typeof window.FormData !== ‘undefined‘); //如果支持html5,那麽就使用進度條 if (feature.fileapi && feature.formdata) { options = $.extend(options, { xhr: function () { var xhr = $.ajaxSettings.xhr(); if (xhr.upload) { xhr.upload.onloadstart = uploadStart; xhr.upload.onprogress = uploadProgress; return xhr; } } }); } $("#form4").ajaxSubmit(options); });
要點說明
- jquery.form.js 仍然需要<form>標簽作為兼容基礎;
- ajaxSubmit(options)方法中的options參數與$.ajax(options)的參數其實是同一個對象,本質就是 ajaxSubmit為 $.ajax 批了一件外套;
- 根據上一點,我們可以使用例子3中同樣的手段實現進度條。
源碼下載:https://pan.baidu.com/s/1eWiOzvio9EVW2WlYeaKUGA
代碼是用VS2015 ASP.NET MVC5寫的,我把bin目錄內的dll都刪了,通過還原 nuget 程序包應該就能運行了。
記錄小文件上傳的幾個例子(含進度條效果,附源碼下載)