jQuery序列化方法serialize()中文亂碼之解決

原因

整個網站的統一編碼是GB2312,可是在一個頁面中有一個表單的要提交的參數是根據條件動態生成的,因此使用了JQuery中的serialize()方法對全部參數進行封裝,再提交到服務器。若提交的數據包含中文,服務器接到的數據中總會存在中文亂碼。

過程

既然是中文亂碼問題,就先從瞭解.Net中轉碼解碼方式開始。如下內容來源自http://blog.sina.com.cn/s/blog_8e743a770101a3gr.html

中文轉Unicode:HttpUtility.UrlEncodeUnicode(string str);html

轉換後中文格式:"%uxxxx"  舉例:"柳_abc123"  轉換結果是:"%u67f3_abc123"java

Unicode轉中文1:HttpUtility.UrlDecode(string str);jquery

str格式:"%uxxxx" ,舉例:"%u67f3_abc123"程序員

Unicode轉中文2:Regex.(string str);ajax

str格式:"\uxxxx"  ,舉例:"\u67f3_abc123"


1.window.escape()與HttpUtility.UrlEncodeUnicode()編碼格式同樣:將一個漢字編碼爲%uxxxx格式服務器

不會被window.escape編碼的字符有:@ _ - . * / +  這與http://www.w3school.com.cn/js/jsref_escape.asp上的解釋不符合app

2.window.encodeURIComponent()與HttpUtility.UrlEncode()編碼格式同樣:將一個漢字編碼爲%xx%xx%xx的格式asp.net

不會被window.encodeURIComponent編碼的字符有:'()*-._!~ 這與 http://www.w3school.com.cn/js/jsref_encodeURIComponent.asp

解釋相符合jsp

不會被HttpUtility.UrlEncode編碼的字符有:'()*-._!相比較而言,HttpUtility.UrlEncode比window.encodeURIComponent多

一個 ~ 編碼 ide

3.不會被window.encodeURI編碼的字符有:-_.!*();/?:@&=$,# 與encodeURIComponent對比,

發現encodeURI不對:;/?:@&=+$,#這些用於分隔 URI 組件的標點符號進行編碼

 

Asp.Net編碼與JS編碼的區別:

1. 不會被HttpUtility.UrlEncodeUnicode編碼的字符與不會被HttpUtility.UrlEncode編碼的字符同樣,而escape和encodeURIComponent
不編碼的字符不同
2. HttpUtility.UrlEncode和HttpUtility.UrlEncodeUnicode會對/編碼,而escape和encodeURIComponent會對/編碼,encodeURI不會

對/編碼

3. HttpUtility.UrlEncode()和HttpUtility.UrlEncodeUnicode()會把空格編碼爲 +,而escape,encodeURIComponent,encodeURI都

會將空格編碼爲

 

使用ajax提交一個字符串:

1. xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

   var postStr="val={name:'梅小偉',age:19}";

   xmlHttp.send(postStr);   

客戶端發送請求以下:

POST /index.aspx HTTP/1.1

Accept: **

Accept-Language: zh-cn

Referer: http://localhost.:3910/Default.aspx

Content-Type: application/x-www-form-urlencoded

Accept-Encoding: gzip, deflate

User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727;
.NET CLR 3.0.04506.648;

.NET CLR 3.5.21022; CIBA; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; baiduie8)

Host: localhost.:3910

Content-Length: 59

Connection: Keep-Alive

Pragma: no-cache

val={name:'梅小偉',age:19}//發現這裏使用了window.encodeURIComponent加碼

在服務端index.aspx中打斷點,發現Request.Form爲:val={name:'%u6885%u5c0f%u4f1f',age:19}(這裏竟然使用了escape編碼,
而不是encodeURIComponent編碼),使用Request.Form[0]取出的值爲「val={name:'梅小偉',age:19}」,使用Request.Form["val"]
取出的值爲null(這是由於客戶端發送請求時將=編碼爲=了,若是使用window.encodeURI這裏就能取出Request.Form["val"]爲:

「{name:'梅小偉',age:19}」了)

 

總結:不是使用get或者post,只要都是使用form的enctype屬性的默認值application/x-www-form-urlencoded,因此若是你要傳
的值都會通過window.encodeURIComponent()編碼再傳送(除了值包含空格不會被編碼爲 ,而是編碼爲+).傳到服務器後,能夠
用Server.UrlDecode()進行解碼。可是要注意,不論是get方式仍是post方式,enctype爲application/x-www-form-urlencoded還
是multipart/form-data,用asp.net在後臺查看Request.QueryString和Request.Form的時候,中文又變成了escape編碼格式,例
如Request.Form=__VIEWSTATE=/wEPDwUJNzgzNDMwNTMzZGSvFy+l0lztppRS7QNr4qmrF4KTw==&mm=%u6556%u5fb7%u8428%u7684(英語

字母不會被編碼,而一些符號使用encodeURIComponent和escape編碼後相同,如=,$等等)。


爲何優先使用encodeURIComponent而不是escape?

escape方 法並不編碼字符+。而咱們知道,在用戶提交的表單字段中,若是有空格,則會被轉化爲+字符,而服務器解析的時候則
會認爲+號表明空格。因爲這個缺 陷,escape方法並不能正確地處理全部的非ASCII字符,你應當儘可能避免使用escape方法,取而
代之,你最好選擇 encodeURIComponent()方法。


繼續搜索一番,找到了問題的根源:serialize()方法自動調用了encodeURIComponent()方法將數據編碼了,然而encodeURIComponent()在編碼字符時,使用的是UTF-8編碼。原帖也給出瞭解決方法,以下:
一、將jquery.js文件中的encodeURIComponent替換爲encodeURI。便可解決中文亂碼。
二、另外一種方式將全部jsp、xml的字符集都設置爲UTF-8 。
JSP   <%@ page language="java" contentType="text/html; charset=UTF-8"%> 
XML  <?xml version="1.0" encoding="UTF-8"?>。
第一種方法好高大上,直接修改jQuery,對於我這種菜鳥顯然行不通,並且會影響到其餘全部的引用jquery.js文件的代碼;第二種方法很直接頗有效,很遺憾,網站使用GB2312編碼格式自有它的道理,並且我只負責的也僅僅是這一個小模塊,只對本身所負責模塊的代碼動刀是程序員行爲準則之一。繼續尋找解決方案。。。。
因而我在博客園中發現了它:http://www.cnblogs.com/fish-li/archive/2012/10/14/2723631.html很是全面的介紹了.Net中各類亂碼出現的緣由以及解決方案。因而直接搬到個人博客上,以便之後能隨時拿來學習,即是上一篇轉載的博客。裏面對我所遇到問題的描述以及給出的解決方法以下: 完全解決encodeURIComponent()與GB2312亂碼問題。又一個高大上!並且在原來頁面的基礎上,僅僅增長了一行代碼!
beforeSend: function(xhr) {    xhr.setRequestHeader("x-charset", "utf-8"); },
膜拜啊!但是,服務端代碼怎麼寫出來的? HttpModule是什麼?HttpApplication、HttpWorkerRequest又是什麼?這個類放到哪?怎麼調用?對於仍是菜鳥的我來講頭好大啊!!

解決

在一次次的嘗試並未解決問題後,我接了杯水,捋了捋煩躁的心情,將眼睛從新放到服務器接到的那幾個中文亂碼上,陷入迷遊:原本是GB2312編碼的、好好的中文漢字!被這個奇葩的serialize()按着UTF8編碼,又被網站默認的GB2312解碼,最終給了我一個魑魅魍魎通常的鬼漢字!艹!!

等等!這就是個人答案!在服務器上接收頁面傳參的部分對參數進行以下處理:

queryStr=context.Request["queryname"];
queryStr = HttpUtility.UrlDecode(HttpUtility.UrlEncode(queryStr, Encoding.GetEncoding("gb2312")), Encoding.UTF8);
很抱歉,我用了兩行代碼。
相關文章
相關標籤/搜索