1. 程式人生 > >解決使用ajaxFileUpload上傳控制元件出現的問題:回撥函式總是進入error或success

解決使用ajaxFileUpload上傳控制元件出現的問題:回撥函式總是進入error或success

上週說到做excel的匯入時,用到了jquery的一個上傳控制元件ajaxFileUpload,但今天測試的時候,卻出現了問題:

我們不妨先來檢視一下ajaxFileUpload的基本語法:

 $.ajaxFileUpload  
    ({  
            url:xxx,  
            secureuri:false,  //上傳處理地址
            fileElementId:'fileToUpload',  //上傳檔案的id
            dataType: 'json',  //傳輸的資料型別,預設為text
           //成功響應後回撥的函式  data為後臺返回的資料 status為成功或失敗狀態
            success: function (data, status)  
            {  
               //some code
            }, 
            //響應失敗後回撥的函式  e為錯誤資訊
            error: function (data, status, e)  
            {  
              //some  code
            }  
              
        }  
    )  

結果我發現,是無論後臺響應是否成功,它都是進入回撥函式error:

而我本地寫的上傳的js如下:

$.ajaxFileUpload({
	url : "demo/import.json",
	//dataType : 'json',
	secureuri : false,
	fileElementId : 'file',
	success : function(res, status) {
               //some code
	},
	error : function(data, status, e) {
               //some code
	}
   }
);	

 後來發現,我竟然把dataType注掉了。。,並且無論後臺是否響應成功,都進的是error回撥……因此我把dataType指定為json,

而檢查我的後臺,發現

我用的google瀏覽器,debug才發現demo/import.json所對應的後臺程式碼:

@RequestMapping("/demo/import.json")
	@ResponseBody
	public String import(@RequestParam(value = "excelFile") MultipartFile excelFile, 
			HttpServletRequest request) {
		String fileName = excelFile.getOriginalFilename();
		String result = "";
		try{
			//some code
			result = "success";
		} catch(Exception e) {
			e.printStackTrace();
			result = "fail";
		}
		return result;
	}

返回的是String,該String並不是json格式的。改之:

@RequestMapping("/demo/import.json")
	@ResponseBody
	public String import(@RequestParam(value = "excelFile") MultipartFile excelFile, 
			HttpServletRequest request) {
		String fileName = excelFile.getOriginalFilename();
		String result = "";
                Map map = new HashMap();
               String jsonStr = null;
		try{
			//some code
			result = "success";
		} catch(Exception e) {
			e.printStackTrace();
			result = "fail";
                      
		}
                map.put("data", result);
                jsonStr = String.valueOf(JSONObject.fromObject(map));
		return jsonStr;
	}

而之前前臺沒指定dataType,因為傳輸的資料型別對應不上,所以無論成功與否都會進入error。

同樣模擬測試後臺響應成功和響應失敗,問題依然出現。。

看到網上說的,可能是ajaxfileupload.js版本的問題,即裡面判斷返回資料型別的js函式:

uploadHttpData: function( r, type ) {
        var data = !type;
        data = type == "xml" || data ? r.responseXML : r.responseText;
        // If the type is "script", eval it in global context
        if ( type == "script" )
            jQuery.globalEval( data );
        // Get the JavaScript object, if JSON is used.
        if ( type == "json" )
        	eval("data = "+data);
        // evaluate scripts within html
        if ( type == "html" )
            jQuery("<div>").html(data).evalScripts();
			//alert($('param', data).each(function(){alert($(this).attr('value'));}));
        return data;
    }

 這個js函式表明,當type為json時,直接把回撥函式引數裡的data指定為後臺給你返回的data,但通過google瀏覽器debug這個方法才發現即使後臺返回值型別改成json格式的String,並指定前臺dataType屬性為json時,獲取到的data為<pre style="word-wrap: break-word; white-space: pre-wrap;">{"data":"success"}</pre>他並不是從後臺獲取到純json格式的字串,改正:

if ( type == "json" )
        	eval("data = "+$(data).html());

 清除瀏覽器快取,重測,即可得到中間的json 串{"data":"success"}。

這樣,無論後臺響應成功與否,它不會只進入error了。

但現在問題又來了,雖然不會只進入error但是問題又來了。。無論是否響應成功,它又只進入success回調了,感覺很無語。

同樣,通過debug,發現前臺回撥時,即使後臺響應失敗,也會給前臺返回一個json {”data:“ "fail"},只要有json,他就會進入success。雖說我可以通過在success裡取data對應的值,根據data對應的值是success還是fail判斷到底是成功響應還是失敗響應,但終歸不太合理。仔細檢查後臺程式碼後,改之:

@RequestMapping("/demo/import.json")
	@ResponseBody
	public String import(@RequestParam(value = "excelFile") MultipartFile excelFile, 
			HttpServletRequest request) {
		
		Map map = new HashMap();
		String jsonStr = null;
		try{
			//some code
			result = "success";
			map.put("data", result);
			jsonStr = String.valueOf(JSONObject.fromObject(map)); //只有響應成功才會得到json格式的字串——前臺進入success回撥
		} catch(Exception e) {
			e.printStackTrace();
			result = "fail";
			//map.put("data", result); //如果響應失敗,則不會生成json格式的字串,返回的就只是一個空的String而已——前臺進入error回撥
		}
		return jsonStr;
	}

 再次模擬成功和失敗響應之後,終於”各找各媽“了——成功響應的進入success回撥,響應失敗的進入error回撥。。

小結:如果是傳輸型別是json格式,如果後臺返回的不是json格式的字串,則前臺只會進error回撥;如果後臺返回的是json格式的字串,但如果響應失敗也給他返回一個json字串時,前臺也會進入success回撥。

推薦一個相對穩定的ajaxFileUpload.js版本下載(見附件):