Šorīt kolēģis man uzdeva jautājumu: es teicu, ka saņemtie parametri ir izkropļoti, ļaujiet man palīdzēt to atrisināt.
Platforma, par kuru ir atbildīgs mans kolēģis, ir veidota Ext.js ietvaru, un web.config konfigurācijas fails ir konfigurēts ar globālo "GB2312" kodējumu:
<globalization requestEncoding="gb2312" responseEncoding="gb2312" fileEncoding="gb2312" culture="zh-CN"/>
Kad frontend iesniedz ķīniešu tekstu, backend saņem kropļotas rakstzīmes ar Request.QueryString["xxx"].
Neatkarīgi no tā, kā jūs dekodējat ar System.Web.HttpUtility.UrlDecode ("xxx", "kodējuma tips"), tas nedarbojas.
Principa apraksts: 1: Pirmā lieta, kas jānosaka, ir tas, ka, iesniedzot klienta URL parametrus, Ext.js tos kodēs pirms to iesniegšanas, un klienta kodējums pēc noklusējuma ir UTF-8 kodējums
2: Tad kāpēc tas ir izkropļots, saņemot parametrus ar Request.QueryString["xxx"]?
Mēs soli pa solim mainām kompilāciju, 2.1: Apskatiet rekvizīta QueryString kodu:
- 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;
- }
- }
Kopēt kodu
2.2: Iegrieziet FillInQueryStringCollection() metodi
- 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);
-
- }
- }
Kopēt kodu
2.3: Izgriezt: 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);
- }
- }
Kopēt koduNo koda QueryStringEncoding sistēma pēc noklusējuma izmanto globalizācijas konfigurācijas mezgla kodēšanas metodi, un, ja nē, noklusējums ir UTF-8 kodējums 2.4: Izgriezt FillFromString (virkne s, bool urlencoded, kodējuma kodējums)
- 代码有点长,就折叠起来了
- 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);
- }
- }
- }
Kopēt koduNo šī brīža mēs konstatējam, ka visas parametru ievades tiek izsauktas vienu reizi: HttpUtility.UrlDecode(str2, kodējums);
Kad klients js iesniedz ķīniešu valodu serverim utf-8 kodējumā, saņemot to ar Request.QueryString, tas vispirms to vienu reizi dekodēs ar globalizācijas konfigurēto gb2312, kā rezultātā rodas izkropļotas rakstzīmes.
1: JS kodēšanas metode ir URT-8
2: Servera pusē ir konfigurēts noklusējums uz GB2312
3: Request.QueryString pēc noklusējuma izsauc HttpUtility.UrlDecode, lai atšifrētu saņemtos parametrus ar sistēmas konfigurācijas kodējumu.
1: Sistēma izvēlas noklusējuma kodējumu šādā secībā: http pieprasījuma galvene - >globalizācijas konfigurācijas mezgls - noklusējuma UTF-8
2: Ievadot URL tieši ķīniešu valodā, dažādas pārlūkprogrammas to var apstrādāt atšķirīgi, piemēram: IE nekodē un iesniedz tieši, Firefox iesniedz URL pēc GB2312 kodējuma.
3: Nekodētām "ķīniešu rakstzīmēm" pēc Request.QueryString iekšējā izsaukuma HttpUtility.UrlDecode izmantošanas, izmantojot gb2312->utf-8,
Ja ķīniešu rakstzīme netiek atrasta, tā pēc noklusējuma tiks konvertēta uz "%ufffd", kā rezultātā tiks iegūtas neatgriezeniskas izkropļotas rakstzīmes.
4: Ceļš uz risinājumu Zinot principu, ir daudz veidu, kā to atrisināt: 1: Globālā apvienošana ir UTF-8 kodējums, kas ietaupa nepatikšanas un raizes.
2: Ja GB2312 ir globāli norādīts, URL ir ķīniešu valoda, un js ir jākodē, piemēram, ext.js ietvars.
Tādā veidā jūs varat to apstrādāt tikai īpaši, norādot kodējumu un dekodēšanu servera pusē. Tā kā noklusējuma sistēma vienu reizi izsauc HttpUtility.UrlDecode ("xxx", sistēmas konfigurācijas kodējums), Tātad jūs atkal izsaucat HttpUtility.UrlEncode ("xxx", sistēmas konfigurētais kodējums), lai atgrieztos pie sākotnējā urt-8 kodējuma parametra
Pēc tam izmantojiet HttpUtility.UrlDecode ("xxx", utf-8), lai to atšifrētu. virkne aaa = pieprasījums. Request.QueryString["admin"]; Mājas īpašnieks virkne a1 = HttpUtility.UrlEncode(aaa, System.Text.Encoding.GetEncoding("GB2312")); virkne a2 = HttpUtility.UrlDecode(a1,System.Text.Encoding.UTF8);
|