利用jquery.form實現異步上傳文件

         實現原理

         目前須要在一個頁面實現多個地方調用上傳控件上傳文件,而且必須是異步上傳。思考半天,想到經過建立動態表單包裹上傳文件域,利用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

相關文章
相關標籤/搜索