Ma reggel egy kollégám kérdezett tőlem: azt mondtam, hogy a kapott paraméterek összezavarosak, hadd segítsek megoldani.
A kollégám által felelős platform Ext.js keretrendszert épített, és a web.config konfigurációs fájl globális "GB2312" kódolással van konfigurálva:
<globalizációs kérésKódolás="gb2312" válaszKódolás="gb2312" fájlKódolás="gb2312" kultúra="zh-CN"/>
Amikor a frontend beküldi a "kínai szöveget", a háttérrendszer összezavarodott karaktereket kap a Request.QueryString["xxx"] betűvel.
Bárhogyan is dekódolsz a System.Web.HttpUtility.UrlDecode("xxx", "kódolási típus") segítségével, az nem működik.
Az elvleírás: 1: Az első dolog, amit meg kell határozni, hogy amikor az ügyfél URL-paramétereit benyújtják, Ext.js kódolja őket, mielőtt beküldené őket, és az ügyfél kódolása alapértelmezetten UTF-8 kódolás
2: Akkor miért zavarodott el, amikor a paramétereket Request.QueryString["xxx"]-szel kapjuk?
Lépésről lépésre fordítjuk a fordítást, 2.1: Nézd meg a QueryString tulajdonság kódját:
- 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;
- }
- }
Kód másolása
2.2: Vágás a FillInQueryStringCollection() metódusba
- Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->private void FillInQueryStringCollection()
- {
- byte[] queryStringBytes = this.QueryStringBytes;
- if (queryStringBytes != null)
- {
- if (queryStringBytes.Length != 0)
- {
- this._queryString.FillFromEncodedBytes(queryStringBytes, this.QueryStringEncoding);
- }
- }//上面是对流字节的处理,即文件上传之类的。
- else if (!string.IsNullOrEmpty(this.QueryStringText))
- {
- //下面这句是对普通文件提交的处理:FillFromString是个切入点,编码切入点是:this.QueryStringEncoding
- this._queryString.FillFromString(this.QueryStringText, true, this.QueryStringEncoding);
-
- }
- }
Kód másolása
2.3: Vágás: QueryStringEncoding
- Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->internal Encoding QueryStringEncoding
- {
- get
- {
- Encoding contentEncoding = this.ContentEncoding;
- if (!contentEncoding.Equals(Encoding.Unicode))
- {
- return contentEncoding;
- }
- return Encoding.UTF8;
- }
- }
- //点击进入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);
- }
- }
Kód másolásaA QueryStringEncoding kódból a rendszer alapértelmezettként a globalizációs konfigurációs csomópont kódolási módszerére vált, ha nem, akkor az alapértelmezett UTF-8 kódolás 2.4: Vágás FillFromStringbe (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)//外面的传值默认是true,所以会执行以下语句
- {
- 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);
- }
- }
- }
Kód másolásaEttől a ponttól kezdve minden paraméter bemenetet egyszer hívunk: HttpUtility.UrlDecode(str2, encoding);
Amikor a js kliens utf-8 kódolással küldi be a szervernek a kínaiat, amikor Request.QueryString-rel kapja meg, először egyszer dekódolja a gb2312-vel, amelyet a globalizáció konfigurált, ami összezavarodott karaktereket eredményez.
1: A JS kódolási módszer az URT-8
2: A szerveroldal beállította az alapértelmezett GB2312-t
3: Az Request.QueryString alapértelmezetten hívja a HttpUtility.UrlDecode-ot, hogy a kapott paramétereket rendszerkonfigurációs kódolással dekódolja.
1: A rendszer az alapértelmezett kódolást a következő sorrendben választja: http kérés fejléc - >globalizációs konfigurációs csomópont - alapértelmezett UTF-8
2: Amikor az URL-t közvetlenül kínai nyelvre írjuk be, különböző böngészők másképp kezelhetik azt, például: az IE nem kódol, és közvetlenül beküldi, a Firefox pedig a GB2312 kódolás után küldi be az URL-t.
3: Kódolatlan "kínai karakterek" esetén, miután a Request.QueryString belső hívást használtak a HttpUtility.UrlDecode, gb2312->utf-8 által,
Ha a kínai karakter nem található, alapértelmezés szerint "%ufffd"-re alakul át, ami visszafordíthatatlan, zavaros karaktereket eredményez.
4: Az út a megoldáshoz Az elv ismeretével sokféle módja van a megoldásának: 1: A globális egységesítés az UTF-8 kódolás, ami megspórolja a gondot és az aggodalmat.
2: Amikor a GB2312 globálisan van megadva, az URL kínai, és a js-t kódolni kell, például ext.js keretrendszert.
Így csak különlegesen tudod kezelni, a kódolást és a dekódolást a szerver oldalon lehet megadni. Mivel az alapértelmezett rendszer egyszer hívja a HttpUtility.UrlDecode-ot ("xxx", a rendszerkonfiguráció kódolása), Tehát ismét hívod a HttpUtility.UrlEncode-ot ("xxx", a rendszer által konfigurált kódolás), hogy visszatérjen az eredeti urt-8 kódolási paraméterhez
Ezután használd a HttpUtility.UrlDecode("xxx", utf-8) kódolást. String AAA = kérés. Request.QueryString["admin"]; Háztulajdonos string a1 = HttpUtility.UrlEncode(aaa, System.Text.Encoding.GetEncoding("GB2312")); string a2 = HttpUtility.UrlDecode(a1,System.Text.Encoding.UTF8);
|