Ajax乱码解决终极方案

canca canca
2007-09-05 15:10
1
0

CAnca

-----------------------------------------------------------------------------------

原创作品,CAnca Software Office.如要转载,请保留版权信息!

http://cancait.blog.163.com 

E-mail:cancait@msn.com

-----------------------------------------------------------------------------------

1.       使用JS中的encodeURIComponentencodeURI方法。

说明:

 

encodeURIComponent(String)

对传递参数进行设置。不编码字符有71个:! '()*-._~0-9a-zA-Z

例:

var url = “<a href=’http://cancait.blog.163.com/name=” + encodeURIComponent(“中国”) + “’>中国</a>”;

 

encodeURI(String)

URL整体转换。不编码字符有82个:!#$&'()*+,,,-./:;=?@_~0-9a-zA-Z

例:

var url = “<a href=’” + encodeURI(“http://cancait.blog.163.com/name=中国”) + “’>中国</a>”;

 

乱码处理实例:

/////////////////////////////////////////////////////////////////////////////////////

初始页面内容如下(hello.jsp)

/////////////////////////////////////////////////////////////////////////////////////
<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
<%String path = request.getContextPath();%>


  
     AJAX <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman';">提交页面</span> <span lang="EN-US"><font face="Times New Roman">

   
     
  
   提交
" onclick="justdo()"/>
   

/////////////////////////////////////////////////////////////////////////////////////
   ajax 请求处理页面( act.jsp )的内容如下 :
/////////////////////////////////////////////////////////////////////////////////////
<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
<%String path = request.getContextPath();%>

<
%@page import="java.net.URLDecoder"%>

  
     ajax deal


    
  
  
   <%
   //
遍历输出参数内容。
   for (Enumeration e = request.getParameterNames(); e.hasMoreElements();) {
    String h = (String) e.nextElement();
    String v = request.getParameter(h);
    String mm =   java.net.URLDecoder.decode(v
"UTF-8");
    System.out.println("
请求参数 : " + h + " = " + mm);
   }
    %>
  

/////////////////////////////////////////////////////////////////////////////////////

 

说明:

java.net.URLencode java.net.URLDecode 分别对应于 JavaScript中的encodeURI decodeURIencodeURIComponent decodeURIComponent.

 

为什么要连续两次调用encodeURI(String)方法呢?是因为Java中的request.getParameter(String)方法会进行一次URI的解码过程,调用时内置的解码过程会导致乱码出现。而URI编码两次后,request.getParameter(String)函数得到的是原信息URI编码一次的内容。接着用java.net.URLDecoder.decode(String str,String codename)方法,将已经编码的URI 转换成原文。

2.       使用JS中的escape 方法。

说明:

escape(String)

0-255以外的unicode值进行编码时输出%u****格式,其它情况下escapeencodeURIencodeURIComponent编码结果相同。

例:

var url = “中国”) + “’>中国”;

 

乱码处理实例:

/////////////////////////////////////////////////////////////////////////////////////

例子跟上面一样。只有这里不同。

(hello.jsp)

post = escape(post);
   post = escape (post);//
两次,很关键

       

(act.jsp)

String h = (String) e.nextElement();
    String v = request.getParameter(h);
String mm =   EscapeUnescape.unescape(v
"UTF-8");
    System.out.println("
请求参数: " + h + " = " + mm);


/////////////////////////////////////////////////////////////////////////////////////

(EscapeUnescape.java)Java中的escapeunescape.内容如下:

/////////////////////////////////////////////////////////////////////////////////////

package cn.kgnews.util;

 

public class EscapeUnescape {

public static String escape(String src) {

int i;

char j;

StringBuffer tmp = new StringBuffer();

tmp.ensureCapacity(src.length() * 6);

 

for (i = 0; i < src.length(); i++) {

 

        j = src.charAt(i);

       

        if (Character.isDigit(j) || Character.isLowerCase(j)

                || Character.isUpperCase(j))

        tmp.append(j);

        else if (j < 256) {

        tmp.append("%");

                if (j < 16)

                tmp.append("0");

        tmp.append(Integer.toString(j 16));

        } else {

        tmp.append("%u");

        tmp.append(Integer.toString(j 16));

        }

        }

return tmp.toString();

}

 

public static String unescape(String src) {

StringBuffer tmp = new StringBuffer();

tmp.ensureCapacity(src.length());

int lastPos = 0 pos = 0;

char ch;

while (lastPos < src.length()) {

        pos = src.indexOf("%" lastPos);

        if (pos == lastPos) {

                if (src.charAt(pos + 1) == 'u') {

                ch = (char) Integer.parseInt(src

                        .substring(pos + 2 pos + 6) 16);

                tmp.append(ch);

                lastPos = pos + 6;

                } else {

                ch = (char) Integer.parseInt(src

                        .substring(pos + 1 pos + 3) 16);

                tmp.append(ch);

                lastPos = pos + 3;

                }

        } else {

                if (pos == -1) {

                tmp.append(src.substring(lastPos));

                lastPos = src.length();

                } else {

                tmp.append(src.substring(lastPos pos));

                lastPos = pos;

                }

        }

        }

return tmp.toString();

}

}

 

/////////////////////////////////////////////////////////////////////////////////////

说明:

EscapeUnescape.java类是Java中的escapeunescape

原理跟上例一样。

 

3.       JavaScript实现java中的URLencodeURLdecode.

说明:

这种方法服务器端代码不必修改。直接request.getParameter()来获取就可以了。

 

JavaScript中的URLencodeURLdecode实现如下:

 

/////////////////////////////////////////////////////////////////////////////////////

(UrlEncodeUrlDecode_gecko.js)IE实现方法如下:

完整代码可到这里下载:

http://www.blueidea.com/user/qswh/qswhU2GB.js

/////////////////////////////////////////////////////////////////////////////////////

var qswhU2GB = […..]; //此数组为GB Unicode对照表

 

function UrlEncode(str){

var icret=""strSpecial="!\"#$%&'()*+/:;<=>?@[\]^`{|}~%";

for(i=0;i

if(str.charCodeAt(i)>=0x4e00){

        c=qswhU2GB[str.charCodeAt(i)-0x4e00];

        ret+="%"+c.slice(02)+"%"+c.slice(-2);

        }

else{

        c=str.charAt(i);

        if(c==" ")

        ret+="+";

        else if(strSpecial.indexOf(c)!=-1)

        ret+="%"+str.charCodeAt(i).toString(16);

        else

        ret+=c;

        }

}

return ret;

}

function UrlDecode(str){

var icdtpret = "";

function findPos(str){

for(var j = 0; j < qswhU2GB.length; j++){

        if(qswhU2GB[j] == str){

        return j;

        }

        }

return -1;

}

 

for(i = 0;i < str.length;){

        c = str.charAt(i);i++;

if(c != "%"){

        if(c == "+"){

        ret += " ";

        }else{

        ret += c;

        }

}else{

        t = str.substring(ii+2);i += 2;

        if(("0x" + t) > 0xA0){

                d = str.substring(i+1i+3);i += 3;

                p = findPos(t + d);

        if(p != -1){

                ret += String.fromCharCode(p + 0x4e00);

                }

        }else{

        ret += String.fromCharCode("0x" + t);

        }

        }

}

return ret;

}

 

function getSpell(strsp){

var ictret="";

if(sp==null)sp="";

for(i=0;i

if(str.charCodeAt(i)>=0x4e00){

        c=parseInt(qswhU2GB[str.charCodeAt(i)-0x4e00]16);

        if(c<55290){

        for(t=qswhSpell.length-1;t>0;t=t-2)if(qswhSpell[t]<=c)break;

        if(t>0)ret+=qswhSpell[t-1]+sp;

        }

        }

}

return ret.substr(0ret.length-sp.length);

}

 

/////////////////////////////////////////////////////////////////////////////////////

(UrlEncodeUrlDecode_ie.js)IE实现方法如下:

/////////////////////////////////////////////////////////////////////////////////////

function UrlEncode(str) {

var ret = "";

var strSpecial = " ~!\"#$%&'()*+-/:;<=>?[]^`{|}~%";

for (var i = 0; i < str.length; i++) {

var chr = str.charAt(i);

strstr = chr;

execScript("c = hex(asc(strstr))" "VBScript");

        if (parseInt("0x" + c) > 127) {

        ret += "%" + c.slice(0 2) + "%" + c.slice(-2);

        } else {

        if (strSpecial.indexOf(chr) != -1) {

        ret += "%" + c.toString(16);

        } else {

        ret += chr;

        }

        }

}

return ret;

}

function UrlDecode(str) {

var ret = "";

for (var i = 0; i < str.length; i++) {

var chr = str.charAt(i);

        if (chr == "+") {

        ret += " ";

        } else {

        if (chr == "%") {

        var asc = str.substring(i + 1 i + 3);

                if (parseInt("0x" + asc) > 127) {

                temp = parseInt("0x" + asc + str.substring(i + 4 i + 6));

                execScript("rt = chr(temp)" "VBScript");

                ret += rt;

                i += 5;

                } else {

                temp = parseInt("0x" + asc);

                execScript("ret = ret + chr(temp)" "VBScript");

                i += 2;

                }

        } else {

        ret += chr;

        }

        }

}

return ret;

}

 

/////////////////////////////////////////////////////////////////////////////////////

(loadcssorjs.js)自动识别浏览器动态导入JS/CSS

实现方法如下:

/////////////////////////////////////////////////////////////////////////////////////

/*

CopyRight(C)CAnca Software Office.

Created by CAnca.2007.9.4

*/

 

function LoadScript(url) {

document.write(" ");

}

function LoadCss(url) {

document.write(" ");

}

 

 

var sSuffix = /msie/.test(navigator.userAgent.toLowerCase()) ? "ie" : "gecko";

LoadScript("js/UrlEncodeUrlDecode_" + sSuffix + ".js");

 

使用方法:

将三个JS文件放在同目录。在页面导入loadcssorjs.js。在要进行编码的地方使用UrlEncode方法即可。

例:

//index.html

…..

 

三种解决方案的比较:

 

第一种,在服务器端需要一次java.net.URLdecode(String)转码。使用起来,不太方便。

第二种,要建立Java版的escapeuncape。在服务器端还是需要一次uncape转码。使用起来,不太方便。

第三种,是最方便的一种方法。只需要客户端进行编码。服务器端可以不做任何修改。唯一缺点的是:firefox浏览网页时,要加载一个150KUrlEncodeUrlDecode_gecko.js文件。影响了浏览速度。(但本人还是推荐使用这方案。)

 

总结:

当然,Ajax实现不乱码,可以不用这三种方案,用这三种方案,只是迫不得已的做法。通常造成乱码的原因有以下几点:

1.xmlhttp 返回的数据默认的字符编码是utf-8,如果前台页面是gb2312或者其它编码数据就会产生乱码。

2.post方法提交数据默认的字符编码是utf-8,如果后台是gb2312或其他编码数据就会产生乱码。

 

解决方法:

 

­推荐方法:由于Javascript沿用java的字符处理方式,内部是使用unicode来处理所有字符的。前台后台都用utf-8编码,这样可以省不少麻烦,从根本上解决了乱码问题.优点是效率高,而且符合目前的形式,utf-8编码本身就是一种比较优秀的编码,没有语言限制.缺点只能调用自己的后台编码或者其他的utf-8的编码。

 

前台更改为

 

 

后台asp中第一行加入如下代码

 

<%@LANGUAGE="JAVASCRIPT" CODEPAGE="65001"%>

<% Response.Charset="utf-8"; %>

<% Session.CodePage=65001; %>

 

后台如果有html代码也需保证

 

 

这里是服务端的asp编码,由于脚本语言是Javascript,所以直接复制到客户端也可以使用!

 

AJAXGET中文的时候解决乱码的方法

 

加上设置字符编码的方法:

response.setHeader("charset""gb2312");

 

说明:

   AJAXGET回一个页面时,RESPONSETEXT里面的中文多半会出现乱码,这是因为xmlhttp在处理返回的responseText的时候,是把resposeBodyUTF-8编码进解码来形成的,如果服务器送出的确实是UTF-8的数据流的时候汉字会正确显示,而送出了GBK编码流的时候就乱了。解决的办法就是在送出的流里面加一个HEADER,指明送出的是什么编码流,这样XMLHTTP就不会乱搞了。

 

PHP:header('Content-Type:text/html;charset=GB2312');

ASP:Response.Charset("GB2312")

JSP:response.setHeader("Charset""GB2312");

 

 

2007-9-5

CAnca

发表评论