今天在项目中做一个导出Excel的功能,客户端网页向服务器提交一个POST请求,发送一个json对象给服务器,这个json对象并不是简单的键值对,而是有好几层深度的json对象。


原有的请求方法是Angular JS中的$http.post(),正常工作,但是总有一些浏览器兼容性等方面的问题,于是考虑把它换成jquery的$ajax()。

代码(要提交的json对象就是下面的postData):

$.ajax({
				type: "POST",
				url: fs.common.baseResourceURL2 + '/api/query/export_excel',
				data: postData,
				dataType: "text",
				success: function(data){
						if(data == 'ok'){
							window.open(fs.common.baseResourceURL2 + "/api/query/download_export_excel");
						}
				}
			});

不过转换的过程中遇到了几个问题:

第一:HTTP 415 ,提交的媒体类型不对

原因:原来的Angular JS $http.post()提交时,json对象不用手动处理,以Request Palyload提交,而改成$ajax()之后,变成了Form Data提交,因此后台无法处理:

Angular $http.post():

Form Data 转换成 Request Palyload_代码            

  jQuery $ajax():

Form Data 转换成 Request Palyload_代码_02


那么,为了适应后台处理的要求,就要把Form Data 改成 Request Palyload,怎么修改呢?网上查到了方法,那就增加请求头:

Content-Type:application/json;charset=UTF-8,

在$ajax()中修改如下:

url: fs.common.baseResourceURL2 + '/api/query/export_excel',
				beforeSend: function(request) {
                        request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
                }, //在beforeSend属性中添加请求头
				data: postData,
增加beforeSend属性,在进行添加请求头的操作。
然后再次发起请求的时候Form Data 就变成了Request Payload,看上去问题解决了,但是又出现了新问题,如下:


第二:Request Payload 乱码

Request Palyload中的内容看上去是乱码,应该是被编码处理过了,隐约能看出来json对象的内容,但这样的内容后台还是无法处理:

Form Data 转换成 Request Palyload_代码_03

解决问题的大致思路如下:

1. 已经是Request Payload了,那么和其他部分应该无关了,应该是postData本身的问题,可能需要指定什么编码属性,也可能是postData格式的问题。

首先尝试指定编码属性,又添加了几个header,无效。

忽然想起,这种形式的POST内容,好像和上传一个文件的时候形式很相似,那么,是不是函数把postData当成文件而不是json处理呢?

然后想起以前遇到过的类似问题,json只是一种格式,字符串的组织形式,说到底它应该是个字符串,于是尝试把postData转换为字符串,如下:

data: JSON.stringify(postData),


再次尝试,OK!问题解决!