目前須要在一個頁面實現多個地方調用上傳控件上傳文件,而且必須是異步上傳。思考半天,想到經過建立動態表單包裹上傳文件域,利用jquery.form實現異步提交表單,從而達到異步上傳的目的,在上傳完畢後移除上傳表單,避免與原有表單造成嵌套,致使原有的表單沒法正常提交。同時該方式還支持一次上傳一個文件,重複上傳或者一次上傳多個文件,具備較好的方便性。javascript
ayscUploadFile方法包含兩個參數, wrapId和postMap。
html
wrapId被指定爲要被上傳表單包裹的位置id。java
postMap是一個對象,主要包含如下信息:jquery
一、表單提交地址Urlgit
因爲上傳文件的表單都是enctype='multipart/form-data',不能使用post提交文本參數,須要使用get方式提交其餘參數,所以要傳遞額外的參數在url中直接帶上參數。github
二、type參數ajax
容許上傳的文件類型json
三、folder參數api
指定上傳文件的自定義存儲子目錄,默認不須要指定。瀏覽器
四、beforeCallback
beforeCallback爲ajax提交表單以前事件觸發函數
五、successCallback
successCallback爲上傳成功後的處理函數
六、errorCallback
errorCallback爲ajax異步提交表單失敗後的處理函數
一、異步上傳文件
二、支持批量上傳文件
function ayscUploadFile(wrapId, postMap){ /*判斷被包裹的id是否存在*/ if(wrapId == "undefined" || wrapId.length == 0){ alert("被包裹的id不存在"); return false; }else{ wrapId = wrapId.indexOf("#") >= 0 ? wrapId : "#"+ wrapId; } if(!(typeof(postMap) == "object")){ alert("上傳配置參數錯誤"); return false; } var url = postMap["url"]; /*判斷url是否爲空*/ if(!(url != "undeifned" && url.length > 0)){ alert("上傳地址錯誤"); return false; }else{ /*上傳文件類型*/ var type = ("type" in postMap) ? postMap["type"] : ""; /*自定義上傳文件目錄*/ var folder = ("folder" in postMap) ? postMap["folder"] : ""; /*url地址加上限制上傳文件的類型*/ if(type.length > 0){ url = adArgsToUrl(url, "type", type); } /*url地址加上自定義的上傳文件存儲位置*/ if(folder.length > 0){ url = adArgsToUrl(url, "folder", folder); } } /*表單id*/ var formId = "frm_"+ wrapId.replace("#", ""); /*生成表單*/ var formContent = "<form id='"+ formId +"' name='"+ formId +"' action='"+ url+"' method='post' enctype='multipart/form-data'></form>"; /*將表單包裹在指定的id上*/ if($("form[id="+ formId +"]").length == 0){ $(wrapId).wrap(formContent); } /*驗證表單中文件域是否已經選擇文件*/ var checkForm = true; $("form[id="+ formId +"] > :file").each(function(){ if(this.value.length == 0){ alert("還沒有選擇文件,請選擇文件"); checkForm = false; return; } }); if(checkForm){ /*回調方法*/ var beforeCallback = postMap["beforeCallback"]; var successCallback = postMap["successCallback"]; var errorCallback = postMap["errorCallback"]; /*異步上傳文件*/ $("#" + formId).ajaxSubmit({ dataType:"html", beforeSend:function(httpRequest){ if(typeof(beforeCallback) == "function"){ if(!beforeCallback.call(null, formId)){ httpRequest.abort(); alert("終止執行ajax異步提交") } }else{ alert("正在上傳文件,請耐心等待,不要關閉瀏覽器"); } }, success:function(responseText){ alert(responseText) /*重置表單,確保容許繼續添加上傳文件*/ resetForm(); if(typeof(successCallback) == "function"){ /*解析返回結果*/ successCallback.call(null, parseResultMap(responseText)); }else{ alert("文件上傳成功"); } }, error:function(responseText){ resetForm(); if(typeof(errorCallback) == "function"){ /*解析返回結果*/ errorCallback.call(null); }else{ alert("網絡通信異常,上傳失敗,請從新上傳或稍後再試"); } } }); } /*重置表單信息*/ function resetForm(){ /*重置上傳表單內容,方便上傳新的文件*/ $("#"+ formId).clearForm(); /*移除表單,恢復原樣,避免表單嵌套*/ $(wrapId).unwrap("#"+ formId); } /*解析返回結果*/ function parseResultMap(responseText){ var resultMap = {}; var jsonObject = eval("("+ responseText +");"); var fileName = ("fileName" in jsonObject) ? jsonObject["fileName"] : ""; var fileSize = ("fileSize" in jsonObject) ? jsonObject["fileSize"] : ""; var fileUrl = ("fileKey" in jsonObject) ? jsonObject["fileKey"] : ""; var fileExt = ("fileExt" in jsonObject) ? jsonObject["fileExt"] : ""; var message = ("message" in jsonObject) ? jsonObject["message"] : "上傳失敗"; var uploadState = ("uploadState" in jsonObject) ? jsonObject["uploadState"] : "0"; fileSize = (parseInt(fileSize)/1024).toFixed(2); resultMap["fileName"] = fileName; resultMap["fileSize"] = fileSize; resultMap["fileUrl"] = fileUrl; resultMap["fileExt"] = fileExt; resultMap["message"] = message; resultMap["uploadState"] = uploadState; return resultMap; } }
上述函數使用須要引入的外部腳本文件
<script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript" src="js/jquery.form.js"></script>
另外特別說明:
beforeSend方法實際上實在$.ajax中,他接收一個XMLHTTPRequest參數,所以若要掛起ajax請求,執行XMLHTTPRequest的abort()便可。
parseResultMap方法爲接收服務器返回的數據並進行處理。、
ajaxSubmit方法實現的異步提交實際上仍是jquery的$.ajax的進一步封裝,方便了你們的使用.
該方法也支持一次上傳多個文件。但必須建立多個文件域控件,到時上傳表單包含這些文件域,實現批量上傳文件。
<div id="divWrap"> <input type="file" id="fileOne" name="fileOne" value="" /> <input type="file" id="fileTwo" name="fileTwo" value="" /> <input type="file" id="fileThree" name="fileThree"value="" /> <input type="file" id="fileFour" name="fileFour" value="" /> </div>
須要批量上傳的文件域必須被包裹在指定的包裹id裏(divWrap),包裹id用於指定動態表單的建立位置。上面的html代碼,就是一個包含多個文件域的實例,這樣就能夠一次上傳多個文件。
另一種 方式能夠曲線實現批量上傳。用戶每上傳完畢一個文件後,容許用戶繼續上傳文件,回調函數把服務器返回的上傳文件信息輸出給頁面,頁面記錄下用戶全部的上傳文件信息。
http://api.jquery.com/Ajax_Events/
http://baike.baidu.com/link?url=zsF_hdb0eZGOtzG2-fwLiHSPJDw0NqZ9GqXScpmBoF3Y_UauuT3HlJrt6raotAsVbVg-_TZQ6zdkh-GYZ91Wn_
http://www.w3school.com.cn/xmldom/dom_http.asp
http://www.cnblogs.com/beniao/archive/2008/03/29/1128914.html
https://github.com/malsup/form