日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Request 接收参数乱码原理解析

發(fā)布時間:2024/1/17 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Request 接收参数乱码原理解析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

起因:

今天早上被同事問了一個問題:說接收到的參數(shù)是亂碼,讓我?guī)椭鉀Q一下。

?

?

實際情景:

同事負(fù)責(zé)的平臺是Ext.js框架搭建的,web.config配置文件里配置了全局為“GB2312”編碼:

<globalization?requestEncoding="gb2312"?responseEncoding="gb2312"?fileEncoding="gb2312"?culture="zh-CN"/>

當(dāng)前臺提交“中文文字”時,后臺用Request.QueryString["xxx"]接收到的是亂碼。

無論用System.Web.HttpUtility.UrlDecode("xxx","編碼類型")怎么解碼都無效。

?

原理說明:

1:首先確定的是:客戶端的url參數(shù)在提交時,Ext.js會對其編碼再提交,而客戶端的編碼默認(rèn)是utf-8編碼

客戶端默認(rèn)有三種編碼函數(shù):escape()?encodeURI()?encodeURIComponent()

?

2:那為什么用Request.QueryString["xxx"]接收參數(shù)時,收到的會是亂碼?

為此,我們必須解開Request.QueryString的原始處理邏輯過程

?

我們步步反編繹,

2.1:看QueryString屬性的代碼:

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->public NameValueCollection QueryString {get{if (this._queryString == null){this._queryString = new HttpValueCollection();if (this._wr != null){this.FillInQueryStringCollection();//重點代碼切入點}this._queryString.MakeReadOnly();}if (this._flags[1]){this._flags.Clear(1);ValidateNameValueCollection(this._queryString, "Request.QueryString");}return this._queryString;} }

  2.2:切入?FillInQueryStringCollection()方法

private void FillInQueryStringCollection() {byte[] queryStringBytes = this.QueryStringBytes;if (queryStringBytes != null){if (queryStringBytes.Length != 0){this._queryString.FillFromEncodedBytes(queryStringBytes, this.QueryStringEncoding);}}//上面是對流字節(jié)的處理,即文件上傳之類的。else if (!string.IsNullOrEmpty(this.QueryStringText)){//下面這句是對普通文件提交的處理:FillFromString是個切入點,編碼切入點是:this.QueryStringEncodingthis._queryString.FillFromString(this.QueryStringText, true, this.QueryStringEncoding);} }

  2.3:切入:QueryStringEncoding

internal Encoding QueryStringEncoding {get{Encoding contentEncoding = this.ContentEncoding;if (!contentEncoding.Equals(Encoding.Unicode)){return contentEncoding;}return Encoding.UTF8;} } //點擊進(jìn)入this.ContentEncoding則為: public Encoding ContentEncoding {get{if (!this._flags[0x20] || (this._encoding == null)){this._encoding = this.GetEncodingFromHeaders();if (this._encoding == null){GlobalizationSection globalization = RuntimeConfig.GetLKGConfig(this._context).Globalization;this._encoding = globalization.RequestEncoding;}this._flags.Set(0x20);}return this._encoding;}set{this._encoding = value;this._flags.Set(0x20);} }

  

說明:

從QueryStringEncoding代碼得出,系統(tǒng)默認(rèn)會先取globalization配置節(jié)點的編碼方式,如果取不到,則默認(rèn)為UTF-8編碼方式

2.4:切入 ?FillFromString(string?s,?bool?urlencoded,?Encoding?encoding)

?

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->internal void FillFromString(string s, bool urlencoded, Encoding encoding) {int num = (s != null) ? s.Length : 0;for (int i = 0; i < num; i++){int startIndex = i;int num4 = -1;while (i < num){char ch = s[i];if (ch == '='){if (num4 < 0){num4 = i;}}else if (ch == '&'){break;}i++;}string str = null;string str2 = null;if (num4 >= 0){str = s.Substring(startIndex, num4 - startIndex);str2 = s.Substring(num4 + 1, (i - num4) - 1);}else{str2 = s.Substring(startIndex, i - startIndex);}if (urlencoded)//外面的傳值默認(rèn)是true,所以會執(zhí)行以下語句{base.Add(HttpUtility.UrlDecode(str, encoding), HttpUtility.UrlDecode(str2, encoding));}else{base.Add(str, str2);}if ((i == (num - 1)) && (s[i] == '&')){base.Add(null, string.Empty);}} }

  

說明:

從這點我們發(fā)現(xiàn):所有的參數(shù)輸入,都調(diào)用了一次:HttpUtility.UrlDecode(str2,?encoding);

3:結(jié)論出來了

當(dāng)客戶端js對中文以utf-8編碼提交到服務(wù)端時,用Request.QueryString接收時,會先以globalization配置的gb2312去解碼一次,于是,產(chǎn)生了亂碼。

所有的起因為:

1:js編碼方式為urt-8

2:服務(wù)端又配置了默認(rèn)為gb2312

3:Request.QueryString默認(rèn)又會調(diào)用HttpUtility.UrlDecode用系統(tǒng)配置編碼去解碼接收參數(shù)。

?

文章補充

1:系統(tǒng)取默認(rèn)編碼的順序為:http請求頭->globalization配置節(jié)點-》默認(rèn)UTF-8

2:在Url直接輸入中文時,不同瀏覽器處理方式可能不同如:ie不進(jìn)行編碼直接提交,firefox對url進(jìn)行g(shù)b2312編碼后提交。

3:對于未編碼“中文字符”,使用Request.QueryString時內(nèi)部調(diào)用HttpUtility.UrlDecode后,由gb2312->utf-8時,

如果查不到該中文字符,默認(rèn)轉(zhuǎn)成"%ufffd",因此出現(xiàn)不可逆亂碼。

?

?

4:解決之路

知道了原理,解決的方式也有多種多樣了:

1:全局統(tǒng)一為UTF-8編碼,省事又省心。

?

2:全局指定了GB2312編碼時,url帶中文,js非編碼不可,如ext.js框架。

這種方式你只能特殊處理,在服務(wù)端指定編碼解碼,
因為默認(rèn)系統(tǒng)調(diào)用了一次HttpUtility.UrlDecode("xxx",系統(tǒng)配置的編碼),
因此你再調(diào)用一次HttpUtility.UrlEncode("xxx",系統(tǒng)配置的編碼),返回到原始urt-8編碼參數(shù)
再用HttpUtility.UrlDecode("xxx",utf-8),解碼即可。

?

5:其它說明:默認(rèn)對進(jìn)行一次解碼的還包括URI屬性,而Request.RawUrl則為原始參數(shù)

http://www.cnblogs.com/cyq1162/archive/2010/11/29/1891124.html

總結(jié)

以上是生活随笔為你收集整理的Request 接收参数乱码原理解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。