日常开发中,经常遇到由于页面不一致,导致由页面表单提交或超连接跳转时中文成了乱码的问题。解决此问题的方法不外乎二:
1.使用统一的页面编码
2.接收参数的时候进行编码转换。
但 是以上两种方法并不是任何时候都能胜任的。本人在开发并维护一个web应用的时候就遇到了这样的问题:在进行系统版本切换时(由.net滚动升级至 java),一个GB2312编码的页面,需要向两个不同的servlet提交请求。一个servlet接收参数使用utf-8编码,另一个使用 GB2312。修改servlet的java代码不太现实,它们都是部署在服务器上的稳定的web应用。统一页面编码就更行不通了,一个网页怎么可能即是 utf-8又是GB2312编码呢?
冥思苦想,想了两个解决方案出来:
1.编写一个独立的servlet作跳板,在其内部进行编码转换
2.写一段javascript来完成编码转换
本来想按照方案1来的,但是发现公司里已经有.net 的牛人写出了javascript脚本,仔细看过不禁拍案叫绝:
<script language="JavaScript" charset="utf-8">
<!--
function utf8(wide) {
var c,s;
var enc = "";
var i = 0;
while(i<wide.length) {
c= wide.charCodeAt(i++);
// handle UTF-16 surrogates
if(c>=0xDC00 && c<0xE000){
continue;
}
if(c>=0xD800 && c<0xDC00) {
if(i>=wide.length){
continue;
}
s= wide.charCodeAt(i++);
if(s<0xDC00 || c>=0xDE00){
continue;
}
c= ((c-0xD800)<<10)+(s-0xDC00)+0x10000;
}
// output value
if(c<0x80){
enc += String.fromCharCode(c);
}
else if(c<0x800){
enc += String.fromCharCode(0xC0+(c>>6),0x80+(c&0x3F));
}
else if(c<0x10000){
enc += String.fromCharCode(0xE0+(c>>12),0x80+(c>>6&0x3F),0x80+(c&0x3F));
}
else{
enc += String.fromCharCode(0xF0+(c>>18),0x80+(c>>12&0x3F),0x80+(c>>6&0x3F),0x80+(c&0x3F));
}
}
return enc;
}
var hexchars = "0123456789ABCDEF";
function toHex(n){
return hexchars.charAt(n>>4)+hexchars.charAt(n&0xF);
}
var okURIchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
function encodeURIComponentNew(s) {
//alert(s);
var s = utf8(s);
var c;
var enc = "";
for(var i=0;i<s.length;i++) {
if(okURIchars.indexOf(s.charAt(i))==-1)
enc+="%"+toHex(s.charCodeAt(i));
else
enc+=s.charAt(i);
}
// document.write(enc);
return enc;
}
// -->
</script>
将如上代码放入GB2312编码的页面,不仅可以进行GB2312->utf-8的转换,还可以进行GB2312->utf-16的转换。
再次感叹javascript的威力!