Šis raksts ir mašīntulkošanas spoguļraksts, lūdzu, noklikšķiniet šeit, lai pārietu uz oriģinālo rakstu.

Skats: 23136|Atbildi: 0

[Avots] c# Pieprasījums saņem izkropļotas rakstzīmes parametriem

[Kopēt saiti]
Publicēts 25.12.2015 18:41:49 | | | |


Š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:

  1. Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->public NameValueCollection QueryString
  2. {
  3.     get
  4.     {
  5.         if (this._queryString == null)
  6.         {
  7.             this._queryString = new HttpValueCollection();
  8.             if (this._wr != null)
  9.             {
  10.                 this.FillInQueryStringCollection();//重点代码切入点
  11.             }
  12.             this._queryString.MakeReadOnly();
  13.         }
  14.         if (this._flags[1])
  15.         {
  16.             this._flags.Clear(1);
  17.             ValidateNameValueCollection(this._queryString, "Request.QueryString");
  18.         }
  19.         return this._queryString;
  20.     }
  21. }
Kopēt kodu

2.2: Iegrieziet FillInQueryStringCollection() metodi

  1. Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->private void FillInQueryStringCollection()
  2. {
  3.     byte[] queryStringBytes = this.QueryStringBytes;
  4.     if (queryStringBytes != null)
  5.     {
  6.         if (queryStringBytes.Length != 0)
  7.         {
  8.             this._queryString.FillFromEncodedBytes(queryStringBytes, this.QueryStringEncoding);
  9.         }
  10.     }//上面是对流字节的处理,即文件上传之类的。
  11.     else if (!string.IsNullOrEmpty(this.QueryStringText))
  12.     {
  13.         //下面这句是对普通文件提交的处理:FillFromString是个切入点,编码切入点是:this.QueryStringEncoding
  14.         this._queryString.FillFromString(this.QueryStringText, true, this.QueryStringEncoding);
  15.         
  16.     }
  17. }
Kopēt kodu

2.3: Izgriezt: QueryStringEncoding

  1. Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->internal Encoding QueryStringEncoding
  2. {
  3.     get
  4.     {
  5.         Encoding contentEncoding = this.ContentEncoding;
  6.         if (!contentEncoding.Equals(Encoding.Unicode))
  7.         {
  8.             return contentEncoding;
  9.         }
  10.         return Encoding.UTF8;
  11.     }
  12. }
  13. //点击进入this.ContentEncoding则为:
  14. public Encoding ContentEncoding
  15. {
  16.     get
  17.     {
  18.         if (!this._flags[0x20] || (this._encoding == null))
  19.         {
  20.             this._encoding = this.GetEncodingFromHeaders();
  21.             if (this._encoding == null)
  22.             {
  23.                 GlobalizationSection globalization = RuntimeConfig.GetLKGConfig(this._context).Globalization;
  24.                 this._encoding = globalization.RequestEncoding;
  25.             }
  26.             this._flags.Set(0x20);
  27.         }
  28.         return this._encoding;
  29.     }
  30.     set
  31.     {
  32.         this._encoding = value;
  33.         this._flags.Set(0x20);
  34.     }
  35. }
Kopēt kodu
No 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)

  1. 代码有点长,就折叠起来了

  2. Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->internal void FillFromString(string s, bool urlencoded, Encoding encoding)
  3. {
  4.     int num = (s != null) ? s.Length : 0;
  5.     for (int i = 0; i < num; i++)
  6.     {
  7.         int startIndex = i;
  8.         int num4 = -1;
  9.         while (i < num)
  10.         {
  11.             char ch = s[i];
  12.             if (ch == '=')
  13.             {
  14.                 if (num4 < 0)
  15.                 {
  16.                     num4 = i;
  17.                 }
  18.             }
  19.             else if (ch == '&')
  20.             {
  21.                 break;
  22.             }
  23.             i++;
  24.         }
  25.         string str = null;
  26.         string str2 = null;
  27.         if (num4 >= 0)
  28.         {
  29.             str = s.Substring(startIndex, num4 - startIndex);
  30.             str2 = s.Substring(num4 + 1, (i - num4) - 1);
  31.         }
  32.         else
  33.         {
  34.             str2 = s.Substring(startIndex, i - startIndex);
  35.         }
  36.         if (urlencoded)//外面的传值默认是true,所以会执行以下语句
  37.         {
  38.             base.Add(HttpUtility.UrlDecode(str, encoding), HttpUtility.UrlDecode(str2, encoding));
  39.         }
  40.         else
  41.         {
  42.             base.Add(str, str2);
  43.         }
  44.         if ((i == (num - 1)) && (s[i] == '&'))
  45.         {
  46.             base.Add(null, string.Empty);
  47.         }
  48.     }
  49. }
Kopēt kodu
No šī 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);








Iepriekšējo:čau
Nākamo:Kāds algoritms, es vairākas dienas esmu nomākts.
Atruna:
Visa programmatūra, programmēšanas materiāli vai raksti, ko publicē Code Farmer Network, ir paredzēti tikai mācību un pētniecības mērķiem; Iepriekš minēto saturu nedrīkst izmantot komerciāliem vai nelikumīgiem mērķiem, pretējā gadījumā lietotājiem ir jāuzņemas visas sekas. Informācija šajā vietnē nāk no interneta, un autortiesību strīdiem nav nekāda sakara ar šo vietni. Iepriekš minētais saturs ir pilnībā jāizdzēš no datora 24 stundu laikā pēc lejupielādes. Ja jums patīk programma, lūdzu, atbalstiet oriģinālu programmatūru, iegādājieties reģistrāciju un iegūstiet labākus oriģinālus pakalpojumus. Ja ir kādi pārkāpumi, lūdzu, sazinieties ar mums pa e-pastu.

Mail To:help@itsvse.com