1.使用 JS中的 encodeURIComponent或 encodeURI方法。
说明:
encodeURIComponent(String)
对传递参数进行设置。不编码字符有 71个: !, ', (, ), *, -, ., _, ~, 0-9, a-z, A-Z。
例:
var url = “中国 ”;
encodeURI(String)
对 URL整体转换。不编码字符有 82个: !, #, $, &, ', (, ), *, +,,, -, ., /, :, ;, =, ?, @, _, ~, 0-9, a-z, A-Z。
例:
var url = “中国 ”;
乱码处理实例:
/
初始页面内容如下 (hello.jsp):
/
AJAX提交页面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 = '/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方式,使用这个来发送内容 ?
}
/ ajax请求处理页面( act.jsp)的内容如下 :
/
< %@pageimport="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和 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 = “中国 ”;
乱码处理实例:
/
例子跟上面一样。只有这里不同。
(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实现方法如下:
完整代码可到这里下载:
/
var qswhU2GB = […..]; //此数组为 GB Unicode对照表
function UrlEncode(str){
var i, c, ret="", strSpecial="!\"#$%&'()*+, /:;<=>?@[\]^`{|}~%";
for(i=0;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
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("");
}
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
window.open(url);
…..
三种解决方案的比较:
第一种, 在服务器端需要一次 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的编码。
前台更改为
后台 asp中第一行加入如下代码
span
------君临天下,舍我其谁------