因POST发送数据之前都需要进行一下URL编码,JavaScript下对应的处理函数为encodeURI 和 encodeURIComponent,
作为JavaScript顶层函数,这俩货只能做UTF-8的URL编码,想用GBK的URL编码?呵呵呵……
上面说了, JavaScript用的Unicode字符集,所以实现起来麻烦大大的。
再说浏览器吧,浏览器的表单提交时会自动将数据进行URL编码,而这个编码方式是根据当前页面的编码来的。
所以说,如果是GBK编码的页面,提交的时候用的就是GBK的URL编码,于是有突破口了吧。
但是啊,用JavaScript去做一个临时表单后去截取数据,想想就麻烦啊,
但是啊,还有如果你在GBK编码的页面设置一个标签的href为中文字符,这个href也会自动将中文进行GBK的URL编码。
早说嘛,这样就好办了。
扯了这么多,再说说jQuery的ajax:
在源代码中有这么一段:
// Convert data if not already a string
if ( s.data && s.processData && typeof s.data !== “string” ) {
s.data = jQuery.param( s.data, s.traditional );
}
就是说,如果ajax时有设置data,然后processData不是false,而且设置的data不是字符串,那么就使用jQuery的param来处理这个设置的data(对象或者数组)。
param方法的功能:创建一个数组或对象序列化的的字符串,适用于一个URL 地址查询字符串或Ajax请求。
网上有所谓的终极解决方案,就是通过重写jQuery的param方法的。
但是,其实……那个方案根本不能用!Unicode编码和URL编码是一回事么?
说到这里就该放代码了:
(function ($) {
// 根据当前页面编码进行URL编码
$.urlEncode = function(s) {
var a, u;
a = document.createElement(‘a’);
a.href = ‘/?_=’ + s;
u = a.href.slice(a.href.indexOf(‘/?_=’) + 4);
return encodeURIComponent(u).replace(/%25([0-9A-F]{2})/gi, ‘%$1’);
};
// 添加 localParam 方法 URL编码使用 $.urlEncode
$.localParam = function(a) {
var prefix,
s = [],
add = function(key, value) {
value = $.isFunction(value) ? value() : (value == null ? ” : value);
s[s.length] = $.urlEncode(key) + ‘=’ + $.urlEncode(value);
},
buildParams = function(prefix, obj) {
var name;
if ($.isArray(obj)) {
$.each(obj, function(i, v) {
buildParams(prefix + ‘[‘ + (typeof v === ‘object’ ? i : ”) + ‘]’, v);
});
} else if ($.type(obj) === ‘object’) {
for (name in obj) {
buildParams(prefix + ‘[‘ + name + ‘]’, obj[name]);
}
} else {
add(prefix, obj);
}
};
if ($.isArray(a) || (a.jquery && !$.isPlainObject(a))) {
$.each(a, function() {
add(this.name, this.value);
});
} else {
for (prefix in a) {
buildParams(prefix, a[prefix], add);
}
}
return s.join(‘&’).replace(/%20/g, ‘+’);
};
} (jQuery));
这里对jQuery 扩展了两个新的方法 urlEncode 和 localParam:
urlEncode 就是根据当前页面编码来进行URL编码的函数,当然了,不作为jQuery 方法也可以,去掉`$.`;
localParam 就是相对原来的 param 方法来的,稍微做了一下修改,为了保持jQuery 的纯洁就不重写param 方法了,默认直接就是对对象做深度递归,URL编码部分使用urlEncode来处理。
使用示例:
// ajax方法
$.ajax({
type: ‘POST’,
url: ‘/path/ajax.php’,
dataType: dataType,
data: $.localParam(data),
});
// post方法
$.post(‘/path/ajax.php’, $.localParam(data), function (s) {
// do something
});
// 使用post方式的load方法
$(selector).load(‘/path/ajax.php #selector’, $.localParam(data), function (s) {
// do something
});
代码中的data可以是对象或者数组,其实跟平时的post一样,只是对要post的数据先用localParam处理一下,通过返回字符串来避免jQuery 的param 方法对数据处理。
补充一下serialize方法处理,jQuery 代码:
serialize: function() {
return jQuery.param( this.serializeArray() );
},
可以看出其实还是param对serializeArray来序列化,
$(selector).serialize();
所以在使用serialize的时候可以改为:
$.localParam($(selector).serializeArray());