ajax上傳檔案的原理與實現,ajax上傳檔案原理
ajax已經很普遍了,但使用 ajax上傳檔案自己卻一直都沒有涉及,我只知道挺複雜的,上傳檔案不同於上傳一般的表單資料,必須特殊處理,知道一般ajax使用上傳都是應用一個虛擬iframe,但由於項目需要,在網上找了找,沒想到找到了兩個支援ajax上傳檔案的jquery外掛程式,jquery.uploadify.js和dropzone.min.js兩個都可以實現ajax上傳檔案,效果也不錯。
1使用jquery.uploadify.js上傳檔案
這種上傳方式,使用了Flash,因此需要引用一個特殊的js檔案swfobject.js,低版本的需要引用,高版本的這個檔案已經包含在jquery.uploadify.js中了。另外低版本的參數和高版本的參數也不太一樣了。
使用Uploadify v3.2.1的完整前台代碼
<html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"> <title></title> <script src="Scripts/jquery-1.8.0.min.js" type="text/javascript"></script> <script src="Styles/jquery.uploadify.js" type="text/javascript"></script> <link href="Styles/uploadify.css" rel="stylesheet" type="text/css" /> <script type="text/javascript"> $(document).ready(function () { $("#uploadify").uploadify({ swf: 'Styles/uploadify.swf', uploader: 'Handler1.ashx?OperationType=upfile',//背景處理地址 fileTypeDesc: '請選擇excel檔案', buttonText: '請選擇excel檔案', fileTypeExts: '*.xls', 'auto': false, onSelectError: function (file, errorCode, errorMsg) { switch (errorCode) { case -100: alert("上傳的檔案數量已經超出系統限制的" + $('#uploadify').uploadify('settings', 'queueSizeLimit') + "個檔案!"); break; case -110: alert("檔案 [" + file.name + "] 大小超出系統限制的" + $('#uploadify').uploadify('settings', 'fileSizeLimit') + "大小!"); break; case -120: alert("檔案 [" + file.name + "] 大小異常!"); break; case -130: alert("檔案 [" + file.name + "] 類型不正確!"); break; } }, onFallback: function () { alert("您未安裝FLASH控制項,無法上傳圖片!請安裝FLASH控制項後再試。"); }, //上傳到伺服器,伺服器返回相應資訊到data裡 onUploadSuccess: function (file, data, response) { alert(data); }, onSelect: function (fileObj) { alert("檔案名稱:" + fileObj.name + "\r\n" + "檔案大小:" + fileObj.size + "\r\n" + "建立時間:" + fileObj.creationdate + "\r\n" + "最後修改時間:" + fileObj.modificationdate + "\r\n" + "檔案類型:" + fileObj.type ); } }); }); function doUplaod() { $('#uploadify').uploadify('upload', '*'); } function closeLoad() { $('#uploadify').uploadify('cancel', '*'); } </script></head><body> <form id="form1" runat="server"> <div> <div> <div id="fileQueue"></div> <input type="file" name="uploadify" id="uploadify" /> <p> <a href="javascript:doUplaod()">上傳</a>| <a href="javascript:closeLoad()">取消上傳</a> </p> </div> </div> </form></body></html>
Uploadify v2.1.0的寫法
由於沒有swfobject.js,需要添加引用
<script src="Scripts/swfobject.js" type="text/javascript"></script>
另外部分參數也不一樣,例如uploader,script
完整的前台代碼
<html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"> <title></title> <script src="Scripts/jquery-1.8.0.min.js" type="text/javascript"></script> <script src="Scripts/jquery.uploadify.v2.1.0.js" type="text/javascript"></script> <link href="Scripts/uploadify.css" rel="stylesheet" type="text/css" /> <script src="Scripts/swfobject.js" type="text/javascript"></script> <script type="text/javascript"> </script> <script type="text/javascript"> $(document).ready(function () { $("#uploadify").uploadify({ 'uploader': 'Scripts/uploadify1.swf', 'script': 'Handler1.ashx?OperationType=upfile', 'cancelImg': 'Scripts/cancel.png', 'folder': 'UploadFile', 'queueID': 'fileQueue', 'auto': false, 'multi': false, 'fileExt': '*.doc;*.xls', 'fileDesc': '請選擇excel檔案', 'onSelect': function (e, queueId, fileObj) { alert("唯一標識:" + queueId + "\r\n" + "檔案名稱:" + fileObj.name + "\r\n" + "檔案大小:" + fileObj.size + "\r\n" + "建立時間:" + fileObj.creationDate + "\r\n" + "最後修改時間:" + fileObj.modificationDate + "\r\n" + "檔案類型:" + fileObj.type ); } }); }); </script></head><body> <form id="form1" runat="server"> <div> <div id="fileQueue"></div> <input type="file" name="uploadify" id="uploadify" /> <p> <a href="javascript:$('#uploadify').uploadifyUpload()">上傳</a>| <a href="javascript:$('#uploadify').uploadifyClearQueue()">取消上傳</a> </p> </div> </form></body></html>
2使用dropzone.min.js上傳檔案
沒有使用Flash,但對瀏覽器要求比較高,例如IE10以上才支援,應該是使用了html5的技術
完整的前端代碼、
<html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"> <title></title> <script src="Scripts/jquery-1.8.0.min.js" type="text/javascript"></script> <script src="Scripts/dropzone.min.js" type="text/javascript"></script> <link href="Scripts/dropzone.css" rel="stylesheet" type="text/css" /> <script type="text/javascript"> jQuery(function ($) { Dropzone.autoDiscover = false; try { var myDropzone = new Dropzone("#dropzone", { paramName: "FileData", // The name that will be used to transfer the file maxFilesize: 5, // MB dictRemoveFile: '移除檔案', dictCancelUpload: '取消上傳', addRemoveLinks: true, uploadMultiple: false, acceptedFiles: '.xls', autoProcessQueue: true, dictRemoveFile: "關閉", dictFileTooBig: '此檔案過大', dictCancelUploadConfirmation: '確定取消上傳嗎?', dictInvalidInputType: "不支援此類型檔案上傳!", parallelUploads: 1, //限制上傳檔案數 url: "Handler1.ashx?OperationType=upfile", init: function () { this.on("success", function (file) { //console.log("File " + file.name + "uploaded"); alert("檔案" + file.name + "上傳成功"); }); this.on("complete", function (file) { this.removeFile(file); }); this.on("removedfile", function (file) { //alert(file.name); }); }, /* accept: function (file, done) { //if (file.name == "11.jpg") { // done("Naha, you don't."); //} //else { done(); },*/ success: function (file, data) { if (data.status === 1) { $scope.uploadImage = data.message; $scope.listUserImages(); } else { //alertService.showAlert({ // content: data.message, // type: 'warning' //}); //$('.dz-error-mark').show(); //alert(data.message); } }, dictDefaultMessage: '<span class="bigger-150 bolder"><i class="ace-icon fa fa-caret-right red"></i> 上傳</span> 檔案 \<span class="smaller-80 grey">點擊</span> <br /> \<i class="upload-icon ace-icon fa fa-cloud-upload blue fa-3x"></i>', dictResponseError: 'Error while uploading file!', //change the previewTemplate to use Bootstrap progress bars previewTemplate: "<div class=\"dz-preview dz-file-preview\">\n <div class=\"dz-details\">\n <div class=\"dz-filename\"><span data-dz-name></span></div>\n <div class=\"dz-size\" data-dz-size></div>\n <img data-dz-thumbnail />\n </div>\n <div class=\"progress progress-small progress-striped active\"><div class=\"progress-bar progress-bar-success\" data-dz-uploadprogress></div></div>\n <div class=\"dz-success-mark\"><span></span></div>\n <div class=\"dz-error-mark\"><span></span></div>\n <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n</div>" }); } catch (e) { alert('Dropzone.js does not support older browsers!'); } }); </script></head><body> <form id="dropzone" runat="server" action="Handler1.ashx?OperationType=upfile" class="dropzone dz-clickable" enctype="multipart/form-data" method="post"> <div class="dz-message" style="width:50px;height:50px;"> <i class="upload-icon ace-icon fa fa-cloud-upload blue fa-3x"></i> </div> <div><div id="FileBed"></div>點擊上傳檔案 <input type="file" multiple="multiple" class="dz-hidden-input" style="visibility: hidden; position: absolute; top: 0px; left: 0px; height: 0px; width: 0px;" /> </div> </form> </body></html>
3幕後處理代碼
public class Handler1 : IHttpHandler { public void ProcessRequest(HttpContext context) { string operatype = context.Request.QueryString["OperationType"]; if (operatype == "upfile") { HttpPostedFile file = context.Request.Files["FileData"]; if (file != null) { string fullPath = System.IO.Path.Combine(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "update"), DateTime.Now.Date.ToString("yyyyMMdd")); file.SaveAs(fullPath + file.FileName); } } context.Response.ContentType = "text/plain"; context.Response.Write("上傳成功"); } public bool IsReusable { get { return false; } } }
原始碼下載