在使用AJAX向服务器端发送中文数据时,出现乱码,折腾了很久,在网上也找了很多解决办法,比如全站UTF-8编码、请求头编码为中文、使用javascript中的escape函数等等,但一一试过均无效。在绝望之际,找到了一篇和我的情况比较相近的文章(详见:http://blog.csdn.net/wallimn/archive/2006/11/12/1380106.aspx),在详细参考这篇文章的做法之后终于把问题解决。
现在,把自己的解决方法写出来,以便有需要的朋友不要再像我那样走弯路。
环境:WinXP + Eclipse,JSP + Struts,页面用JavaScript结合Ajax控制,页面和服务器都使用UTF-8编码。
MyActionForm的属性:
private String nameEn = null;
private String nameSc = null;
private String nameTc = null;
|
Action(MyAction) 的excute方法里面代码:
MyActionForm maForm = (MyActionForm)form;
// must decoding, or else it will disorderly code
// 第二个设编码参数一定要设
String strNameEn = java.net.URLDecoder.decode(maForm.getNameEn(), "UTF-8");
String strNameSc = java.net.URLDecoder.decode(maForm.getNameSc(), "UTF-8");
String strNameTc = java.net.URLDecoder.decode(maForm.getNameTc(), "UTF-8");
System.out.println("strNameEn: " + strNameEn);
System.out.println("strNameSc: " + strNameSc);
System.out.println("strNameTc: " + strNameTc);
|
客户端代码:
<html>
<head>
<title>Test Ajax Send Chinese</title>
<script language="javascript">
<!--
var req;
function retrieveURL(url)
{
if(window.XMLHttpRequest){ // Non-IE browsers
req = new XMLHttpRequest();
}else if (window.ActiveXObject) { // IE browsers
req = new ActiveXObject("Microsoft.XMLHTTP");
}
if(req){
req.onreadystatechange = callback;
try {
req.open("POST", url, true);
req.setRequestHeader("CONTENT-TYPE", "application/x-www-form-urlencoded");
} catch (e) {
alert(e);
}
req.send(null);
}
}
function callback()
{
if (req.readyState == 4) { // Complete
if (req.status == 200) { // OK response
processMessage();
} else {
alert("Problem: " + req.statusText);
}
}
}
function processMessage()
{
alert('Test OK!');
}
function trim(srcString)
{
return srcString.replace(/^\s*/,'').replace(/\s*$/,'');
}
/*该函数就是测试函数,jsp表单上提供strNameEn、strNameSc、strNameTc三项内容*/
function test()
{
if(trim(document.MyActionForm.nameEn.value)==''||
trim(document.MyActionForm.nameSc.value)==''||
trim(document.MyActionForm.nameTc.value)=='')
{
alert('NO INPUT!');
return;
}
var url = 'MyAction.do';
url += '&nameEn=' + document.MyActionForm.nameEn.value +
'&nameSc=' + document.MyActionForm.nameSc.value +
'&nameTc=' + document.MyActionForm.nameTc.value;
url = encodeURI(encodeURI(url)); //这里一定要执行两次encodeURI,否则Action端会提示NULL
retrieveURL(url);
}
//-->
</script>
</head>
<body>
<h2>Test Ajax Send Chinese</h2>
<hr>
<html:form action="MyAction.do">
<table>
<tr><td>Name(English) </td><td><input type="text" name="nameEn"/></td></tr>
<tr><td>Name(Simplified Chinese) </td><td><input type="text" name="nameSc"/></td></tr>
<tr><td>Name(Traditional Chinese) </td><td><input type="text" name="nameTc"/></td></tr>
<tr><td align="right"><p><input type="button" name="btnSubmit" value="Test" onclick="test();"/></td><td> </td></tr>
</table>
<html:form>
</body>
</html>
|
注:
1、上面的MyAction对应你的Action,MyActionForm对应你的ActionForm
2、该方法对用“GET”(上面例子用“POST”)方法发送也有效,即javascript函数retrieveURL里面的语句:
req.open("POST", url, true);
|
改成
req.open("GET", url, true);
|
也行
3、关键地方在于编码:
url = encodeURI(encodeURI(url));
|
和解码:
String strNameEn = java.net.URLDecoder.decode(maForm.nameEn(), "UTF-8");
String strNameSc = java.net.URLDecoder.decode(maForm.nameSc(), "UTF-8");
String strNameTc = java.net.URLDecoder.decode(maForm.nameTc(), "UTF-8");
|
后记:
从后来的实践中发现,事实上这种情况不止存在于Ajax发送url到servlet,几乎所有的从Web client 发送url数据到Web server情况,也都存在这种问题,解决方法都可以类似或者相同。也就是说,这中情况实质上是Web client通过网络和Web Server之间的通信而引起的。