原理:

jquery form插件ajax上传文件的原理,

1、浏览器实现了XMLHttpRequest level2规范的,则插件使用xhr直接提交文件。通常来说chrome、firefox都实现了xhr level2规范

2、浏览器只实现了XMLHttpRequest level1规范的,则插件使用form+iframe方式,实现页面无刷新上传文件。通常来说,IE8及以下都属于此列。

    有关form+iframe方式实现的页面无刷新文件上传,请参考博文form+iframe仿ajax上传文件


jquery form上传文件的样例代码

html代码

<div>
	<h2>jquery form插件上传文件 - 示例程序</h2>
    <form id="uploadForm" method="post" >
    	<input type="file" name="Filedata"></input>
    	<input id="subbtn" type="submit" >
    </form> 

 	
</div>



js代码

$('input[name=Filedata]').change(function () {
	initUploadForm();
});

function initUploadForm () {
		var url = "/flash/upload";
		var options = { 
                    type: 'post',
                    url: url,
		    success:function(ret) { 
		    	//var tempret = eval('('+ret+')');
		    	alert(tempret.result);
		    },
		    error:function (responseText, statusText) {
		    	alert("shang chuan cuo wu");
		    }
		}; 
		// pass options to ajaxForm 
		$('#uploadForm').ajaxForm(options);
}




后续问题:

上述代码在chrome下运行没有问题,在IE8浏览器下提示“下载json文件”。通过查阅资料得知,IE8下会使用form+iframe方式提交文件,因为iframe只识别html和xml,所以当服务器端返回的内容类型是application/json时,iframe不识别,浏览器提示下载,故要求IE8浏览器下,服务器端返回内容类型必须是text/html。


修正:

服务器端,根据客户端是否是ajax请求,来分别设置Content-Type,比如

String ajaxmethod = request.getHeader("X-Requested-With");
		if(StringUtils.isBlank(ajaxmethod)){//非ajax请求
			response.setContentType("text/html;charset=UTF-8");
			
		}else{
			response.setContentType("application/json;charset=UTF-8");
			
		}
Map<String,String>  map = new HashMap<String,String> ();
		map.put("result", "success");
		String jsonstr = new Gson().toJson(map);
		try {
			response.getWriter().write(jsonstr);
		} catch (IOException e) {
			e.printStackTrace();
		}



客户端,如果仅仅设置服务器端,客户端又会出问题。在IE8下会出现undefined,究其原因是success函数接收的参数是json字符串,没有转化为json 对象,所以,alert(ret.result)时,ret还是json串,ret.result值就是undefined。

解决方案就是,在客户端判断,返回值是否是json字符串,返回值是json字符串,就进行转换。返回值不是json字符串,就不再进行转换;

if(typeof ret == "string"){
		    		var tempret = eval('('+ret+')');
			    	alert(tempret.result);
		    	}else{
			    	alert(ret.result);
		    	}




jquery form上传文件原理原文:


htmlExampleTarget (output will be added below):



This page demonstrates the Form Plugin's file upload capabilities. There is no special coding required to handle file uploads. File input elements are automatically detected and processed for you.

Browsers that support the XMLHttpRequest Level 2 will be able to upload files seamlessly and even get progress updates as the upload proceeds. For older browsers, a fallback technology is used which involves iframes since it is not possible to upload files using the level 1 implmenentation of the XMLHttpRequest object. This is a common fallback technique, but it has inherent limitations. The iframe element is used as the target of the form's submit operation which means that the server response is written to the iframe. This is fine if the response type is HTML or XML, but doesn't work as well if the response type is script or JSON, both of which often contain characters that need to be repesented using entity references when found in HTML markup.

To account for the challenges of script and JSON responses when using the iframe mode, the Form Plugin allows these responses to be embedded in a textarea element and it is recommended that you do so for these response types when used in conjuction with file uploads and older browsers.

text/html, otherwise Internet Explorer will prompt the user to download a "file".

Also note that if there is no file input in the form then the request uses normal XHR to submit the form (not an iframe). This puts the burden on your server code to know when to use a textarea and when not to. If you like, you can use the iframe option of the plugin to force it to always use an iframe mode and then your server can always embed the response in a textarea. But the recommended solution is to test for the 'X-Requested-With' request header. If the value of that header is 'XMLHttpRequest' then you know that the form was posted via ajax. The following PHP snippet shows how you can be sure to return content successfully:



参考资料:

jquery form Plugin doc