jQuery ajax在GBK編碼下表單提交終極解決方案(非二次編碼方法)
當(dāng)jquery ajax在utf-8編碼下(頁(yè)面utf-8,接收utf-8),無(wú)任何問(wèn)題??梢哉ost、get,處理頁(yè)面直接獲取正確的內(nèi)容。
但在以下情況下:
GBK -> AJAX POST ->GBK
UTF-8 -> AJAX POST ->GBK
后臺(tái)代碼無(wú)法獲取正確的內(nèi)容,通常表現(xiàn)為獲取到奇怪字符、問(wèn)號(hào)。
經(jīng)典解決方法:
1:發(fā)送頁(yè)面、接收頁(yè)面均采用UTF-8編碼。
2:發(fā)送頁(yè)面在調(diào)用ajax post方法之前,將含有中文內(nèi)容的input用encodeURIComponent編碼一次,而接收頁(yè)面則調(diào)用解碼方法( 如:java.net.urldecoder.decode("接收到內(nèi)容","utf-8") )。
其中,第一種方法無(wú)疑是最簡(jiǎn)單、最直接,但往往不符合實(shí)際,因?yàn)楹芏囗?xiàng)目并不是使用utf-8編碼,例如國(guó)內(nèi)大部分使用gbk編碼,也不可能為了解決這樣一個(gè)問(wèn)題,而將整個(gè)項(xiàng)目轉(zhuǎn)換為utf-8編碼,成本太大,風(fēng)險(xiǎn)太高。
第二方法,是現(xiàn)在最多人使用的方法,俗稱二次編碼,為什么叫二次編碼,等下會(huì)解釋??蛻舳司幋a兩次,服務(wù)端解碼兩次。但這種方法不好的地方,就是前臺(tái)手動(dòng)編碼一次,后臺(tái)再手動(dòng)解碼一次,稍不留神就會(huì)忘記,而且代碼摻和前臺(tái)邏輯。
交互過(guò)程:
當(dāng)我們使用表單按照傳統(tǒng)方式post提交時(shí)候(非AJAX提交),瀏覽器會(huì)根據(jù)當(dāng)前頁(yè)面編碼,encode一次,然后發(fā)送到服務(wù)端,服務(wù)端接收到表單,會(huì)自動(dòng)dencode一次,通常這個(gè)過(guò)程是對(duì)程序是透明的,因此加上手動(dòng)編碼、解碼,就變成上面所說(shuō)的二次編碼。
但當(dāng)我們使用AJAX方式提交時(shí)候,瀏覽器并不會(huì)自動(dòng)替我們encode,因此在jquery中有這樣的一段代碼:
ajax: function( s ) {
// Extend the settings, but re-extend 's' so that it can be
// checked again later (in the test suite, specifically)
s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
var jsonp, jsre = /=?(&|$)/g, status, data,
type = s.type.toUpperCase();
// convert data if not already a string
if ( s.data && s.processData && typeof s.data !== "string" )
s.data = jQuery.param(s.data);
........
}
以上是jquery的ajax方法的代碼片段,下面是正常調(diào)用jquery ajax post的代碼:
$.ajax({
url: ajaxurl,
type: 'POST',
dataType: 'html',
timeout: 20000,//超時(shí)時(shí)間設(shè)定
data:para,//參數(shù)設(shè)置
success: function(html){
}
});
通過(guò)上面代碼可以知道,當(dāng)設(shè)置了data時(shí)候,jquery內(nèi)部會(huì)調(diào)用jQuery.param方法對(duì)參數(shù)encode(執(zhí)行本應(yīng)瀏覽器處理的encode)。
jQuery.param=function( a ) {
var s = [ ];
function add( key, value ){
s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
};
// 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.param end
解決方法:
encodeURIComponent會(huì)以u(píng)tf-8編碼,在gbk編碼下,可不可以以gbk進(jìn)行編碼呢?
如果還在打encodeURIComponent主意的話,那不好意思,encodeURIComponent只會(huì)utf-8編碼,并沒(méi)有其他api進(jìn)行其他編碼;不過(guò),別擔(dān)心,看看下面:
encodeURIComponent,它是將中文、韓文等特殊字符轉(zhuǎn)換成utf-8格式的url編碼。
escape對(duì)0-255以外的unicode值進(jìn)行編碼時(shí)輸出%u****格式,其它情況下escape,encodeURI,encodeURIComponent編碼結(jié)果相同。
哈哈,看到希望吧?沒(méi)錯(cuò),就是用escape代替encodeURIComponent方法,不過(guò)必須注意:
escape不編碼字符有69個(gè):*,+,-,.,/,@,_,0-9,a-z,A-Z
encodeURIComponent不編碼字符有71個(gè):!, ',(,),*,-,.,_,~,0-9,a-z,A-Z
使用了escape之后必須對(duì)加號(hào)進(jìn)行編碼,否則,當(dāng)內(nèi)容含有加號(hào)時(shí)候會(huì)被服務(wù)端翻譯為空格。
終于知道解決辦法了,重寫(xiě)jquery代碼:
jQuery.param=function( a ) {
var s = [ ];
var encode=function(str){
str=escape(str);
str=str.replace(/+/g,"%u002B");
return str;
};
function add( key, value ){
s[ s.length ] = encode(key) + '=' + encode(value);
};
// 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的源文件重寫(xiě),可以在你項(xiàng)目的javascript貼上,覆蓋它原有的方法,不過(guò)必須在jquery加載之后。
經(jīng)初步驗(yàn)證,上面那段代碼在utf-8編碼也可以工作正常,大概是編碼成unicode的緣故吧。
這樣,就不是需要使用什么二次編碼,即影響前臺(tái),又影響后臺(tái)。gbk編碼下ajax post不再是問(wèn)題了,此乃是終極解決方法。哈哈。
有興趣的可以到http://www.open-lib.com/Forum/Read_69_1.action與作者交流。
相關(guān)文章
jQuery實(shí)現(xiàn)磁力圖片跟隨效果完整示例
這篇文章主要介紹了jQuery實(shí)現(xiàn)磁力圖片跟隨效果,結(jié)合完整實(shí)例形式分析了jQuery事件響應(yīng)及animate方法實(shí)現(xiàn)帶緩沖效果的圖片跟隨效果,需要的朋友可以參考下2016-09-09
Jquery+AJAX實(shí)現(xiàn)無(wú)刷新上傳并重命名文件操作示例【PHP后臺(tái)接收】
這篇文章主要介紹了Jquery+AJAX實(shí)現(xiàn)無(wú)刷新上傳并重命名文件操作,結(jié)合實(shí)例形式分析了jQuery+ajax前臺(tái)上傳文件與PHP后臺(tái)接收處理相關(guān)操作技巧,需要的朋友可以參考下2020-05-05
基于Jquery插件開(kāi)發(fā)之圖片放大鏡效果(仿淘寶)
公司某個(gè)網(wǎng)站,需要實(shí)現(xiàn)圖片預(yù)覽效果,并能像淘寶一樣實(shí)現(xiàn)局部分大,使用jquery的朋友可以參考下。2011-11-11
jquery的Theme和Theme Switcher使用小結(jié)
jquery的Theme和Theme Switcher使用總結(jié),學(xué)習(xí)jquery Theme的朋友可以參考下。2010-09-09
jquery簡(jiǎn)單實(shí)現(xiàn)幻燈片的方法
這篇文章主要介紹了jquery簡(jiǎn)單實(shí)現(xiàn)幻燈片的方法,核心的js代碼只有9行即可實(shí)現(xiàn)幻燈切換效果,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-08-08
jquery實(shí)現(xiàn)根據(jù)瀏覽器窗口大小自動(dòng)縮放圖片的方法
這篇文章主要介紹了jquery實(shí)現(xiàn)根據(jù)瀏覽器窗口大小自動(dòng)縮放圖片的方法,涉及jquery操作頁(yè)面元素屬性與樣式的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07
jQuery實(shí)現(xiàn)jQuery-form.js實(shí)現(xiàn)異步上傳文件
jquery.form.js是一個(gè)非常強(qiáng)大的用于表單提交的插件。這篇文章主要介紹了jQuery實(shí)現(xiàn)jQuery-form.js實(shí)現(xiàn)異步上傳文件,有興趣的可以了解一下。2017-04-04
jQuery旋轉(zhuǎn)插件—rotate支持(ie/Firefox/SafariOpera/Chrome)
網(wǎng)上發(fā)現(xiàn)一個(gè)很有意思的jQuery旋轉(zhuǎn)插件,支持Internet Explorer 6.0+ 、Firefox 2.0 、Safari 3 、Opera 9 、Google Chrome,高級(jí)瀏覽器下使用Transform,低版本ie使用VML實(shí)現(xiàn),感興趣的朋友可以了解下2013-01-01

