对于亚洲开发者而言,不可避免地需要发送包含非西欧字符的请求参数,而这些请求参数在传输过程中的编码将直接影响服务器的处理。如果发送的请求里不包含非西欧字符,将不会有任何问题;但一旦包含了非西字符,将不会有任何问题;但一旦包含了非西欧字符的请求参数,则可能出现异常。
下面的简单应用通过文本输入获取用户输入,然后分别使用两种方式发送请求,服务器负责用户请求,并将请求参数在控制台中输出。首先看服务器程序。
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
//需要写这句话,解决中文乱码问题,异步post请求默认采用utf-8字符集来编码请求参数
request.setCharacterEncoding("utf-8");
System.out.println(request.getParameter("value"));
%>
上面的服务器响应页面没有生成作何响应,所以
不必用responseText接收响应而只是打印了value请求参数的值,所以也不用在open()方法之前,设置
onreadystatechange来设置回调函数。本应用专门用于分析客户端页面提供了两种方法来发送请求,分别GET和POST方式发送请求。下面是客户端的页面代码。
<!DOCTYPE html>
<html>
<head>
<title>first.html</title>
<meta name="keywords" content="keyword1,keyword2,keyword3">
<meta name="description" content="this is my page">
<meta name="content-type" content="text/html; charset=UTF-8">
<!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
</head>
<body>
<input type="text" name="text" type="text" size="70"/><br>
<input type="button" value="GET发送"
οnclick='getSend(document.getElementById("text").value)'/>
<input type="button" value="POST发送"
οnclick='postSend(document.getElementById("text").value)'/>
<script type="text/javascript">
var xmlrequest;
function createXMLHttpRequest(){
if(window.XMLHttpRequest){
xmlrequest = new XMLHttpRequest();
}
else if (window.ActionXObject){
try{
xmlrequest = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e){
try{
xmlrequest = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e){}
}
}
}
function postSend(value){
createXMLHttpRequest();
var uri= "show.jsp";
xmlrequest.open("POST", uri, true);
xmlrequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xmlrequest.send("value="+value);
}
function getSend(value){
createXMLHttpRequest();
var uri= "show.jsp?value="+value;
xmlrequest.open("get", uri, true);
xmlrequest.send(null);
}
</script>
</body>
</html>
输入中文,当使用GET方式发送请求时,请求参数变成了乱码。编码问题也是Ajax应用必须处理的问题,对于POST请求很好处理,异步POST请求默认采用UTF-8字符集来编码请求参数,因此只需调用HttpServletRequest的setCharacterEncoding("UTF-8")
字符集来编码请求参数,因此只需调用HttpServletRequest的setCharacterEncoding("UTF-8")即可解决乱码问题。服务器采用如下代码即可获得正确的POST请求参数。
另外服器端还可以这样写
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
//处理POST请求
if(request.getMethod().equalsIgnoreCase("POST")){
request.setCharacterEncoding("UTF-8");
System.out.println(request.getParameter("value"));
}
//处理GET请求
else if(request.getMethod().equalsIgnoreCase("GET")){
String tmp = request.getParameter("value");
String a = new String(tmp.getBytes("ISO-8859-1"),"<span style="color:#ff0000;">utf-8</span>");
System.out.println(a);
}
%><strong>
</strong>
可能你用上面的代码用一些浏览器不会发生乱的现象,但事实上,问题依然没有得到解决。如果我们将浏览器更换成其它的浏览器,有可能在文本中输入中文,然后单击Get发送,将看到Tomcat按台中有可再次发生乱码。显然上面的红色编码需要根据客户端浏览器进行改变。
如果你用Firefox发送非西欧字字符请求参数时,可以在发现无论怎样改变编码,都会发生乱码。
解决这个问题的唯一做法是在发送请求的HTML页面固定的URL Encode,手动编码包含非西欧字符的请求参数,这样就可控制请求。即在客户端的HTML页面采用如下Java代码:
//将包含非西欧字符的请求参数用GBK字符集进行编码
java.net.URLEncoder.encode(请求参数,"GBK");
然后再在服务端采用如下代码
new String(请求参数.getByges("ISO-8859-1","GBK"));
这个过程相当烦琐,而且需要HTML页面中使用Java API,相当不合时宜。因此通常建议发送POST请求,尽量使用GET请求,理由如下:
1.处理GET请求的请求参数参数比罗烦琐。
2.当请求参数包含的数据太多时,GET请求可能丢失参数。
3.当两次GET请求的请求参数相同时,Internet Exporer将直接使用服器上次的缓存,根本不会重新发请求,这对于自动刷新页面相当不利。