日期:2014-05-16  浏览次数:20688 次

AJAX传输中文在各平台的兼容性问题和解决方案

原创 ? AJAX传输中文在各平台的兼容性问题和解决方案 收藏

我主要针对IE和FF进行讨论,google的chorme和IE相近。

首先解释几个字符集转码的只是要点已方便后面阐述。
1.java 平台在JVM中运行的字符串为unicode,jsp或servlet的getParamter方法将传进来的不管什么编码的字符串都以ISO- 8859-1编码转成unicode,在输出时在使用ISO-8859-1转回输出,这样在程序开发中不会出现乱码,但在web开发中就非常容易出现乱码
2. 在ajax传输中文字符是,FF和IE所采用的机制是不同的,FF是将所有的字符自动转化成utf-8再进行传输,而在接受字符串是先从头部获取字符集类 型,如果没有在判断<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />中的 字符集类型,而IE恰恰相反,在ajax传中文时,使用平台默认字符集,中文平台的话一般式是GBK,而在接受字符串是先判读<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /中的字符集,在判读头部信息中的字符集类型

好了,这两点理解以后,下面解释起来就方便了。

(1)encodeURI: 在IE和Chrome中,ajax发送的是平台默认的字符编码GBK,通过encodeURI将GBK和一些特殊字符转换成utf-8(想了解 encodeURI的转化详情,可以看我前一篇blog),而在FF中,发送的编码默认为utf-8,所以GBK的编码有FF自动转为utf-8并进行发 送,对utf-8编码调用encodeURI方法,则不会改变字符的编码(因为它已经是utf-8了,再编一次也一样)
(2)一般在服务器端会自动对传入的字符串进行url解码
(3)request.getParameter方法又使字符串用ISO-8859-1解码
(4)使用String.getByte("ISO-8859-1")编码为字节数组
(5)在使用new Stirng(str,"utf-8")解码为unicode,然后就可以在JVM中处理了,和一般在程序中创建的字符串一样了
(6)如果你使用System.out.print输出的话,JVM回根据OS默认字符集编码输出
(7) 如果你要输出到html中的话,为了各平台的兼容性,使用response.setCharacterEncoding设置头部字符集,在html页面中 也使用<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />指定页面编码


说到这里,整个过程大概就是这样了,下面show一下code,来作为这篇文章的结尾把

html:
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
? <head>
? ??? <meta http-equiv="Content-Type" content="text/html; charset=GBK" />
??? <title>My JSP 'MyJsp.jsp' starting page</title>
? </head>
?
? <script type="text/javascript">
??? function createXHR(){
??? ??? var request;
??? ??? try{
??? ??? ??? request =? new ActiveXObject('Msxml2.XMLHTTP');
??? ??? }catch(e){
??? ??? ??? try{
??? ??? ??? ??? request = new ActiveXObject('Microsoft.XMLHTTP');
??? ??? ??? }catch(e){
??? ??? ??? ??? try{
??? ??? ??? ??? ??? request =? new XMLHttpRequest();
??? ??? ??? ??? }catch(e){
??? ??? ??? ??? ??? alert('创建XMLHttpRequest失败');
??? ??? ??? ??? ??? return null;
??? ??? ??? ??? }
??? ??? ??? }
??? ??? }
??? ??? return request;
??? }
??? </script>
???
??? <script type="text/javascript">
??? ??? var xmlHttp = createXHR();
??? ??? var url = 'servlet/HandleServlet?name=胡乐费';
??? ??? if(xmlHttp != null){
??? ??? ??? xmlHttp.open('GET',encodeURI(url),true);
??? ??? ??? xmlHttp.onreadystatechange = updatePage;
??? ??? ??? xmlHttp.send(null);
??? ??? }else{
??? ??? ??? alert('创建失败');
??? ??? }
??? ???
??? ??? function updatePage(){
??? ??? ??? ??? if(xmlHttp.readyState == 4){
??? ??? ??? ??? ??? if(xmlHttp.status == 200){
??? ??? ??? ??? ??? ??? alert(xmlHttp.responseText);
??? ??? ??? ??? ??? }
??? ??? ??? ??? }
??? ??? ??? }
??? </script>
?
? <body>
??? <input type="button" name="btn" value="send" />
???
? </body>
</html>

服务器端servlet:
package com.mst.im;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HandleServlet extends HttpServlet {

??? public void doGet(HttpServletRequest request, HttpServletResponse response)
??? ??? ??? throws ServletException, IOException {

??? ??? request.setCharacterEncoding("GBK");
??? ??? response.setChar