在javascript中汉字的编码真是个很烦人的问题。js默认的是unicode编码,使用charAt函数返回的就是unicode16编码。其实要是只是unicode编码也没有什么,不知道为什么那些西方国家哪根筋不对,觉得unicode多字节字符用的少,只存储字母太浪费了,又搞出了utf-8这个编码。让我很有一种把这帮人暴打一顿的冲动。utf-8存储汉字要3个字节,就为了西方人使用字母存储少一个字节,我们就得多一个字节。而且关键就是这个utf-8搞的使用jquery中ajax功能汉字很容易碰到乱码的现象。看来谁掌握世界就是好,一切便利都由着他们的习惯。抱怨归抱怨,现实问题还是要解决的。
为了避免乱码,服务器和客户端要使用相同的编码,如果都是utf-8就不存在问题。单当服务器是gbk时,就会有问题,因为在jQuery的ajax提交的utf-8编码的数据。如果是get方法好解决,只要提前编码就可以了。post就很麻烦了因为在jQuery中提交参数时使用了encodeURIComponent这个函数,而这个函数返回值是使用utf-8的。如果不调用encodeURIComponent就不会有这个问题,网上有人写了这么一个函数替换jQuery.param方法
比较一下,还是决定采用了修改jQuery源码的方法,将param定义的原函数改为如下,并在ajaxSettings中加入charset:"utf-8",调用param时改为d.data=f.param(d.data,d.traditional,d.charset),这样就可以使用charset属性了。
为了避免乱码,服务器和客户端要使用相同的编码,如果都是utf-8就不存在问题。单当服务器是gbk时,就会有问题,因为在jQuery的ajax提交的utf-8编码的数据。如果是get方法好解决,只要提前编码就可以了。post就很麻烦了因为在jQuery中提交参数时使用了encodeURIComponent这个函数,而这个函数返回值是使用utf-8的。如果不调用encodeURIComponent就不会有这个问题,网上有人写了这么一个函数替换jQuery.param方法
jQuery.param = function(a) {
var s = [];
function add( key, value ){
s[ s.length ] = escape(key,1) + '=' + escape(value,1);
};
// If an array was passed in, assume that it is an array
// of form elements
if ( jQuery.isArray(a) || a.jquery )
// Serialize the form elements
jQuery.each( a, function(){
add( this.name, this.value );
});
// Otherwise, assume that it's an object of key/value pairs
else
// Serialize the key/values
for ( var j in a )
// If the value is an array then the key names need to be repeated
if ( jQuery.isArray(a[j]) )
jQuery.each( a[j], function(){
add( j, this );
});
else
add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] );
// Return the resulting serialization
return s.join("&").replace(/%20/g, "+");
}
这个只要在引用jQuery之后,使用ajax之前就可以了。修改后使用的是escape方法,这个转换的是unicode编码,现在的服务器可以自动识别。一般不会有乱码。如果怕服务器不能识别,那只能发送gbk编码的字符串。这就不能使用jQuery,只有用最基本的XMLHttpRequest来实现ajax,我做了如下示例:
function submitsql(){
var xhr;
if(window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else if(window.ActiveXObject) {
try {
xhr = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
xhr = false;
}
}
} else xhr = false;
if(xhr) {
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
if (xhr.status==200) {// 200 = OK
// ...our code here...
eval("var result = " + this.responseText);
var output = $("#exec_result");
output.html("");
var i,j,tt = "";
if(result.title.length == 0) {
if(result.error) {
output.html("<p>执行["+result.result+"]错误: "+result.error+"</p>");
} else {
output.html("<p>成功执行["+result.result+"]</p>");
}
} else {
for (i in result.title) {
if(tt){
tt = tt + " | " + result.title[i]
} else {
tt = "<p>" + result.title[i];
}
}
tt = tt + "</p>";
output.append(tt);
for (i in result.records) {
var rcd = result.records[i];
tt = "";
for (j in rcd) {
if(tt){
tt = tt + " | " + rcd[j];
} else {
tt = "<li>" + rcd[j];
}
}
tt = tt + "</li>";
output.append(tt);
}
}
} else {
alert(this.responseText);
//alert("Problem retrieving XML data");
}
}
}
xhr.open("POST", "execresult.asp");
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("sqltext="+$("#sqltext")[0].value.urlEncode());
}
}
其中的urlEncode()方法声明如下:
String.prototype.urlEncode = function() {
var r = "";
for (var i = 0; i < this.length; i++) {
var chr =this.charAt(i)
var code = GetByteCode(chr);
if (code.length > 2) {
var b1 = code.substr(0, code.length - 2);
var b2 = code.substr(code.length - 2);
r += "%" + b1 + "%" + b2;
} else {
//!, ',(,),*,-,.,_,~,0-9,a-z,A-Z
if(/!|\'|\(|\)|\*|\-|\.|_|\~|[0-9]|[a-z]|[A-Z]/.test(chr))
r += chr;
else if(code=="20")
r += "+";
else
r += "%" + code;
}
}
return r;
}
在这个函数申明中调用了GetByteCode函数,这是一个vbscript函数:
Function GetByteCode(ch)
GetByteCode = Hex(Asc(ch))
End Function
调用这个函数会对浏览器有很大的限制。可是万能的Javascript不支持读取字符串的实际编码,只好动用简陋的vbscript了。如果一定想实现可以通过查表的方法实现,不过那个会使文件变大。不知道你们有没有实现这个功能的javascript函数,反正我是没有的。这个方法还有一个缺陷就是修改了String对象原型方法,可能会产生一些难以预料的错误,比如遍历字符串实例的时候,可能会产生令人费解的异常。只能说javascript太强悍了,非一般人所能理解。
比较一下,还是决定采用了修改jQuery源码的方法,将param定义的原函数改为如下,并在ajaxSettings中加入charset:"utf-8",调用param时改为d.data=f.param(d.data,d.traditional,d.charset),这样就可以使用charset属性了。
function(a,c,i){typeof c=="string"&&(i=c,c=b);var d=[],h=function(a){return (i||f.ajaxSettings.charset)=="utf-8"?encodeURIComponent(a):escape(a,1);},e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=h(a)+"="+h(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)bY(g,a[g],c,e);return d.join("&").replace(bz,"+")}