解决使用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版本下载(见附件):

 

相关推荐