Ajax乱码解决终极方案

[quote][url]http://q.163.com/plaza/blog/cancait/2133574420078531011642/#2133574420078531011642[/url][/quote]
原创作品,CAnca Software Office.如要转载,请保留版权信息!

http://cancait.blog.163.com

E-mail:cancait@msn.com

1. 使用JS中的encodeURIComponent或encodeURI方法。

说明:



encodeURIComponent(String)

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

例:

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



encodeURI(String)

对URL整体转换。不编码字符有82个:!,#,$,&,',(,),*,+,,,-,.,/,:,;,=,?,@,_,~,0-9,a-z,A-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();%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>AJAX提交页面</title>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<script type="text/javascript">
function justdo(){
var post="name=王力猛&email=wallimn@sohu.com&bokee=http://wallimn.bokee.com";
post = encodeURI(post);
post = encodeURI(post);//两次,很关键
var xmlObj = new ActiveXObject('Msxml2.XMLHTTP');
var URL = '<%= path%>/page/act.jsp';//文件名需要调整成测试时的相应位置?
xmlObj.open ('post',URL,true);
xmlObj.setrequestheader("cache-control","no-cache");
xmlObj.setrequestheader("Content-Type","application/x-www-form-urlencoded");
xmlObj.send (post);//注意:POST方式,使用这个来发送内容?
}
</script>
</head>
<body>
<input type="button" value="提交" οnclick="justdo()"/>
</body>
</html>
/
  ajax请求处理页面(act.jsp)的内容如下:
/
<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
<%String path = request.getContextPath();%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@page import="java.net.URLDecoder"%>
<html>
<head>
<title>ajax deal</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
</head>
<body>
<%
//遍历输出参数内容。
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);
}
%>
</body>
</html>
/



说明:

java.net.URLencode 和 java.net.URLDecode 分别对应于 JavaScript中的encodeURI 和 decodeURI、encodeURIComponent 和 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****格式,其它情况下escape,encodeURI,encodeURIComponent编码结果相同。

例:

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



乱码处理实例:

/

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

(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中的escape和unescape.内容如下:

/


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中的escape和unescape。

原理跟上例一样。



3. 用JavaScript实现java中的URLencode跟URLdecode.

说明:

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



JavaScript中的URLencode跟URLdecode实现如下:



/

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

完整代码可到这里下载:

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

/

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



function UrlEncode(str){

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

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

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

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

ret+="%"+c.slice(0,2)+"%"+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 i,c,d,t,p,ret = "";


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(i,i+2);i += 2;

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

d = str.substring(i+1,i+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(str,sp){

var i,c,t,ret="";

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

for(i=0;i<str.length;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(0,ret.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("<scr" + "ipt type=\"text/javascript\" src=\"" + url + "\" οnerrοr=\"alert('Error loading ' + this.src);\"></scr" + "ipt>");

}

function LoadCss(url) {

document.write("<link href=\"" + url + "\" type=\"text/css\" rel=\"stylesheet\" οnerrοr=\"alert('Error loading ' + this.src);\" />");

}





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

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



使用方法:

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

例:

//index.html

<html>

<head>

<script language=”javascript” src=”js/loadcssorjs.js”></script>

<script language=”javascript”>

var url = “http://cancait.blog.163.com/name=” + UrlEncode(“中国人”);

window.open(url);

</script>

</head>

<body>

…..

</body>

</html>



三种解决方案的比较:



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

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

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



总结:

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

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

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



解决方法:



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



前台更改为



<meta http-equiv="Content-Type" content="text/html; charset=utf-8">



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



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

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

<% Session.CodePage=65001; %>



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



<meta http-equiv="Content-Type" content="text/html; charset=utf-8">



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



AJAX在GET中文的时候解决乱码的方法



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

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



说明:

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



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

ASP:Response.Charset("GB2312")

JSP:response.setHeader("Charset","GB2312");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值