一般情况下,URL 中的参数应使用 url 编码规则,即把参数字符串中除了 -_. 之外的所有非字母数字字符都将被替换成百分号(%)后跟两位十六进制数,空格则编码为加号(+)。但是对于带有中文的参数来说,这种编码会使编码后的字符串变得很长。如果希望有短一点的方式对参数编码,可以采用 base64 编码方式对字符串进行编码,但是 base64 编码方式不能处理 JavaScript 中的中文,因为 JavaScript 中的中文都是以 UTF-16 方式保存的。而 base64 只能处理单字节字符,所以不能直接用 base64 对带有中文的 JavaScript 字符串进行编码。但是可以通过 utf.js 这个程序中提供的 utf16to8 来将 UTF-16 编码的中文先转化为 UTF-8 方式,然后再进行 base64 编码。这样编码后的字符串,在传递到服务器端后可以直接通过 base64_decode 解码成 UTF-8 的中文字符串。但是还有个问题需要注意。base64 编码中使用了加号(+),而 + 在 URL 传递时会被当成空格,因此必须要将 base64 编码后的字符串中的加号替换成 %2B 才能当作 URL 参数进行传递。否则在服务器端解码后就会出错。
原来在编写 PHPRPC 1.1 的 JavaScript 客户端实现时,就是因为没有注意到这个问题,所以在传递中文参数时,有时候传递的参数正确,有时候参数在服务器端解码时就会出错。后来费了好大劲才发现是这个问题。
代码:
/**
* base64编码工具类
* @author wanggang
* @version 2010-12-31
*/
public class Base64Util {
/**
* 将 s 进行 BASE64 编码
* @param s
* @return
*/
public static String encode(byte[] s) {
if (s == null)
return null;
return (new sun.misc.BASE64Encoder()).encode(s);
}
/**
* 将 s 进行 BASE64 编码,针对url的编码
* @param s
* @return
*/
public static String encodeForUrl(byte[] s){
if (s == null)
return null;
String standerBase64 = encode(s);
String encodeForUrl = standerBase64;
//转成针对url的base64编码
encodeForUrl = encodeForUrl.replace("=", "");
encodeForUrl = encodeForUrl.replace("+", "*");
encodeForUrl = encodeForUrl.replace("/", "-");
//去除换行
encodeForUrl = encodeForUrl.replace("\n", "");
encodeForUrl = encodeForUrl.replace("\r", "");
//转换*号为 -x-
//防止有违反协议的字符
encodeForUrl = encodeSpecialLetter1(encodeForUrl);
return encodeForUrl;
}
/**
* 转换*号为 -x-,
为了防止有违反协议的字符,-x 转换为-xx
* @param str
* @return
*/
private static String encodeSpecialLetter1(String str){
str = str.replace("-x", "-xx");
str = str.replace("*", "-x-");
return str;
}
/**
* 转换 -x-号为*,-xx转换为-x
* @param str
* @return
*/
private static String decodeSpecialLetter1(String str){
str = str.replace("-x-", "*");
str = str.replace("-xx", "-x");
return str;
}
/**
* 将 s 进行 BASE64 编码
* @param s
* @return
*/
public static String encode(String s) {
if (s == null)
return null;
return encode(s.getBytes());
}
/**将 BASE64 编码的字符串 s 进行解码
*
* @param s
* @return
*/
public static byte[] decode(String s) {
if (s == null)
return null;
sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
try {
byte[] b = decoder.decodeBuffer(s);
return b;
} catch (Exception e) {
return null;
}
}
/**将 BASE64 编码的字符串 s 进行解码
*
* @param s
* @return
*/
public static byte[] decodeForUrl(String s) {
if (s == null)
return null;
s = decodeSpecialLetter1(s);
s = s.replace("*", "+");
s = s.replace("-", "/");
s += "=";
sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
try {
byte[] b = decoder.decodeBuffer(s );
return b;
} catch (Exception e) {
return null;
}
}
/**
* @param args
*/
public static void main(String[] args) {
String a = "将 s 进行 BASE64 编码,针对url的编码将 s 进行 BASE64 编码,针对url的编码将 s 进行 BASE64 编码,针对url的编码将 s 进行 BASE64 编码,针对url的编码将 s 进行 BASE64 编码,针对url的编码将 s 进行 BASE64 编码,针对url的编码将 s 进行 BASE64 编码,针对url的编码将 s 进行 BASE64 编码,针对url的编码将 s 进行 BASE64 编码,针对url的编码将 s 进行 BASE64 编码,针对url的编码userId=1441&mailId=981&date=2011-02-15-62";
String b = encodeForUrl(a.getBytes());
// b = b.replace("\n", "");
// b = b.replace("\r", "");
System.out.println(b);
System.out.println(new String(decodeForUrl(b)));
b = encode(a.getBytes());
System.out.println(b);
System.out.println(new String(decode(b)));
}
}
联系客服