当利用XMLHttpRequest提交中文数据到服务器端时候,ajax默认编码为utf8,提交中文会发生乱码。为了解决这个问题,baidu了一天,研究了一天,现在把这些心得写下来,以备忘。(我这人健忘,^_^)
首先明确一点:要想彻底没有乱码的烦恼,那就将整个程序使用utf8编码吧。但是我们在php编程中却难免遇到中文乱码问题。
AJAX处理数据出现乱码从程序执行的过程来讲分为两种:
一种是发送给后台程序的中文本身就是乱码,因为zxmlHTTP沿用的是javascript的字处理机制,使用UTF-8编码。但是后台页面使用GB2312或者其它类型编码的话,接收到的数据自然就是乱码了。
另一种是接受到数据再返回的时候,出现字符乱码。这也是因为后台页面使用的编码和 Javascript编码不同造成的。服务器脚本返回的字符默认会使用服务器编码例如GB2312。
下面就来解决这两个问题:
(1) 服务器发回数据乱码的情况:
出现这种情况,我们只要在服务器发回数据的页面加上一个定义编码的文件头即可。 定义文件头信息的时候根据脚本的不同,可以使用以下方式:
PHP:header("Content-Type:text/html;charset=GB2312");
ASP:Response.Charset("GB2312")
JSP:response.setHeader("Charset","GB2312");
(2) 发送中文信息乱码的情况:
其实不管是怎样的编码,我们输入的中文字符都会被正确的以UTF-8格式发送到服务器端,只是在服务器接收的时候没有按照我们预期的方式去解码,而是使用了服务器默认的字符编码方式,通常是GB2312来解码信息。那我们看到的字符自然就是错误的。
我们都知道,XMLHTTP有两种发送数据的方式,一种是GET,一种是POST。
1、 GET的乱码问题:
这个解决起来比较简单,只要加上一个定义编码的Header信息即可:
setRequestHeader("Content-Type","text/html; encoding=gb2312");
这样客户端以GET方式发送到服务器去的数据会被服务器脚本正确的理解为GB2312方式,从而进行解码。
2、 POST的乱码问题:
比较难的部分是使用POST方法发送数据的时候,上面的方法就失效了。因为POST数据使用的Content-type使用的是:
xmlObj.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
没有定义字符编码的地方。我在这个问题的解决上遇到了很大的困难,但是目前已经找到一种比较好的解决方法。
首先在客户端,中文字符在发送到服务器端之前进行URL编码。也就是使用函数encodeURI():
postStr = "remark=" + encodeURI(document. form1.remark.value);
xmlhttp.open("POST", "./modules/mm/inventory/inv_adjustSubmit.php", true);
xmlhttp.onreadystatechange = inv_response;
xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");
xmlhttp.send(postStr);
然后在服务器端接收到值之后使用iconv()函数将字符串重新编码一下就好了!
header("Content-Type:text/html;charset=GBK");
$remark = iconv("UTF-8","GBK",$_POST["remark"]);
注意:此处使用GBK编码,是因为我们在连接数据库的时候使用
mysql_query("SET NAMES 'GBK'");//显示中文
所以,如果此处改成GB2312,那么在插入中文数据到数据库中时会出现问题。
Warning:
1、为了使你的页面少写乱码的烦恼,最好在每个页面都加上编码:meta记得要在script脚本输出之前,否则有可能会乱码。
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title> HPE Inventory System </title>
<script type="text/javascript" src="js/jscalendar-1.0/calendar.js"></script>
</head>
2、记得在每个AJAX输出页面加上这句话:
header("Content-Type:text/html;charset=GB2312");