中文问题是和做WEB的程序员形影不离的, jsp页面的中文问题,Url传参的中文问题,request取值的中文问题…….现在Ajax日趋成熟了,它的中文问题也一样浮出水面了。
其实万变不离其宗,中文问题就是编码问题,我们知道所有的字符集,不管是英文,操作符,标点符号,最基本的编码方式就是ISO-8859-1,中文的编码方式现在最常用的就是GBK,GB2312,UTF-8三种,这三种都是继承自ISO-8859-1,所以只要把握了底层最基本的编码,不管是ajax还是struts,中文问题的解决都是一脉相承的。
好,那我们来看看一个完整的ajax流程,一步步的来剖析它的中文问题及解决方法。
首先是页面:JSP页面的编码方式决定了页面上中文的显示,这点应该都很清楚。要使jsp页面中文不是乱码
这样就可以指定该页面的中文编码为UTF-8了(用UTF-8的原因是因为xml的编码方式都是UTF-8的,而ajax是和xml紧密相连的,jsp页面及之后的ajax请求参数的提交,servlet中往客户端写输出流都统一为UTF-8,对于ajax的处理是相当有必要的)。
<%
@ page contentType
=
"
text/html;charset=UTF-8
"
%>
然后就是ajax请求时传递的中文了,我们知道ajax请求虽是异步的,但它也是一个HTTP请求,所以它也会有HTTP Header, URL等这些参数,如果我们发送ajax请求时需要传递中文参数,最好的办法就是在客户端就完成对HTTP请求中中文数据的编码,否则浏览器默认是用ISO-8859-1编码发送http请求的。这里说的中文数据包括两部分:
一是Http Header中的URL参数,比如
Tomcat配置URI的方法如下(Tomcat5.X以上必须设定该参数,否则它会采用一种非ISO-8859-1的编码方式,这样即使服务端再request.setCharaterEncoding()都没法了,必定乱码!):
< a
href
=”test.jsp?param1=中文参数1¶m2=中文参数2
>
这类传参时的中文,这种中文编码的解决办法最好是让应用服务器来做,比如我们最常用的
< Connector port
="8080"
maxThreads
="150"
minSpareThreads
="25"
maxSpareThreads
="75"
enableLookups
="false"
acceptCount
="100"
debug
="0"
connectionTimeout
="20000"
proxyPort
="80"
disableUploadTimeout
="true"
URIEncoding
="UTF-8"
/>
二是http请求中body部分的中文,这就是表单中的数据了,这部分ajax的HttpRequest有专门的方法设置:如下所示:
request.setRequestHeader( ' Content-Type '
,
'
application/x-www-form-urlencoded;charset=UTF-8
'
);
这样Http Body部分的中文就都已经编码为UTF-8了。,
好了,既然客户端浏览器发送ajax请求时请求的内容都已经用UTF-8编码了,那么传到服务端的数据就已经是编码后的中文数据了,服务端的request就不需要通过request.SetCharaterEncodin()方式再设定编码格式了。这点跟Struts是最大的区别,我们通常看到的Struts对编码问题的解决是通过过滤器,即对所有发送到后台服务端的请求都实现通过这个过滤器,在这个过滤器中设定request的编码方式。实际上这两种方式是殊途同归的,ajax是在客户端就做了编码,发送到服务端当然不需要设置了,而Struts在客户端submit的时候没有做任何设置,那发送到服务端的肯定是ISO-8859-1的数据了,所以需要在过滤器中指定一下,这样request 发现其中的数据有中文,就会对其进行编码了。
接下来服务端完成了业务逻辑,要将结果返回给客户端,那么同样的问题来了,还记得文中最开头的时候我们在jsp页面设定的吗?那里面指定的是UTF-8编码,那么我们现在往jsp页面写输出流的时候是不是也应该编码成和页面的中文编码方式一致呢?答案是肯定的,我们的ajax返回数据时应该加上response的ContentType:
contentType
!这样向客户端写的数据中的中文也是UTF-8编码了,客户端js脚本获取到request.responseXML也好,responseText也好,里面的数据都不会有乱码了。
response.setContentType( " text/xml;charset=UTF-8 " );
response.setContentType( " text/xml;charset=UTF-8 " );
response.setHeader( " Pragma " ,
"
no-cache
"
);
//
HTTP 1.0
response.setDateHeader( " Expires " ,
0
);
//
prevents caching at the proxy server
PrintWriter out = response.getWriter();
out.write(outXML);
out.flush();
out.close();
OK
至此ajax的中文问题已全部解决,从最初的jsp页面看过来,中文就是一个编码方式的问题,出现乱码的原因大部分是在错误的时间,错误的地点进行了编码的操作,且编码的类型一会儿GBK,一会儿GB2312,一会儿UTF-8,当然数据会乱掉了。实际上如果熟悉了HTTP协议,对编码的问题有一个清晰的了解,按照上述方法处理,中文是一点问题都没有的。
------------------------------------------------------
在js,html.jsp中默认都是ISO-8859-1编码。所以在jsp代码中接受中文需要:
String key = request.getParameter("key");
key = new String(key.getBytes("iso-8859-1"),"gbk");