Tämä artikkeli on konekäännöksen peiliartikkeli, klikkaa tästä siirtyäksesi alkuperäiseen artikkeliin.

Näkymä: 23136|Vastaus: 0

[Lähde] c# Pyyntö vastaanottaa sekavia merkkejä parametreille

[Kopioi linkki]
Julkaistu 25.12.2015 18.41.49 | | | |


Tänä aamuna kollega esitti minulta kysymyksen: sanoin, että saadut parametrit olivat sekaisin, autan ratkaisemaan sen.


Alusta, josta kollegani vastaa, on rakennettu Ext.js kehykseen, ja web.config-konfiguraatiotiedosto on konfiguroitu globaalilla "GB2312"-koodauksella:

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

Kun frontend lähettää "kiinalaisen tekstin", taustajärjestelmä saa sekaisin olevia merkkejä Request.QueryString["xxx"].

Riippumatta siitä, miten dekoodaat System.Web.HttpUtility.UrlDecode("xxx", "encoding type"), se ei toimi.

Periaatteen kuvaus:
1: Ensimmäinen asia, joka tulee todeta, on, että kun asiakkaan URL-parametrit toimitetaan, Ext.js koodaa ne ennen lähettämistä, ja asiakkaan koodaus on oletuksena UTF-8-koodaus


2: Miksi se sitten on sekaisin, kun vastaanotetaan parametreja Request.QueryString["xxx"]?

Käännämme käännöksen askel askeleelta,
2.1: Katso QueryString-ominaisuuden koodia:

  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. }
Kopioi koodi

2.2: Leikkaa FillInQueryStringCollection()-metodiin

  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. }
Kopioi koodi

2.3: Leikkaus: 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. }
Kopioi koodi
QueryStringEncoding-koodista järjestelmä käyttää oletuksena globalisaatiokonfiguraatiosolmun koodausmenetelmää, ja jos ei, oletus on UTF-8-koodaus
2.4: Leikkaa FillFromStringiin (string s, bool urlencoded, koodauskoodaus)

  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. }
Kopioi koodi
Tästä eteenpäin kaikki parametrisyötteet kutsutaan kerran: HttpUtility.UrlDecode(str2, encoding);

Kun asiakas js lähettää kiinaa palvelimelle utf-8-koodauksessa, vastaanottaessaan sen Request.QueryStringillä, se purkaa sen ensin kerran gb2312:lla, joka on globalisaation määrittämä, mikä johtaa sekavoihin merkkeihin.

1: JS-koodausmenetelmä on URT-8

2: Palvelinpuoli on konfiguroinut oletusasetukseksi GB2312

3: Request.QueryString kutsuu oletuksena HttpUtility.UrlDecodea purkaakseen vastaanotetut parametrit järjestelmäkonfiguraatiokoodauksella.

1: Järjestelmä valitsee oletuskoodauksen seuraavassa järjestyksessä: http-pyyntöotsikko - >globalisaatiokonfiguraatiosolmu - oletus UTF-8

2: Kun URL syötetään suoraan kiinaksi, eri selaimet voivat käsitellä sitä eri tavoin, esimerkiksi: IE ei koodaa ja lähettää suoraan, Firefox lähettää URL-osoitteen GB2312-koodauksen jälkeen.

3: Koodaamattomille "kiinalaisille merkeille", käyttäen Request.QueryStringin sisäistä kutsua HttpUtility.UrlDecode, tekijänä gb2312->utf-8,

Jos kiinalaista merkkiä ei löydy, se muunnetaan oletuksena muotoon "%ufffd", mikä johtaa peruuttamattomiin sekavoihin merkkeihin.

4: Ratkaisun tie
Kun tuntee periaatteen, on monia tapoja ratkaista se:
1: Globaali yhtenäisyys on UTF-8-koodaus, mikä säästää vaivaa ja huolta.

2: Kun GB2312 määritellään globaalisti, url on kiinaksi, ja js täytyy koodata, kuten ext.js framework.

Näin voit hoitaa sen vain erityisesti, määrittäen koodauksen ja purkamisen palvelinpuolella.
Koska oletusjärjestelmä kutsuu HttpUtility.UrlDecodea ("xxx", järjestelmän konfiguroinnin koodaus) kerran,
Kutsut siis HttpUtility.UrlEncodea ("xxx", järjestelmän määrittämä koodaus) uudelleen palataksesi alkuperäiseen urt-8-koodausparametriin

Sitten käytä HttpUtility.UrlDecode("xxx", utf-8) purkaaksesi sen.
merkkijono aaa = pyyntö. Request.QueryString["admin"];    Asunnonomistaja
                            string a1 = HttpUtility.UrlEncode(aaa, System.Text.Encoding.GetEncoding("GB2312"));
                            merkkijono a2 = HttpUtility.UrlDecode(a1,System.Text.Encoding.UTF8);








Edellinen:Moikka
Seuraava:Mikä algoritmi, olen ollut masentunut useita päiviä.
Vastuuvapauslauseke:
Kaikki Code Farmer Networkin julkaisemat ohjelmistot, ohjelmamateriaalit tai artikkelit ovat tarkoitettu vain oppimis- ja tutkimustarkoituksiin; Yllä mainittua sisältöä ei saa käyttää kaupallisiin tai laittomiin tarkoituksiin, muuten käyttäjät joutuvat kantamaan kaikki seuraukset. Tämän sivuston tiedot ovat peräisin internetistä, eikä tekijänoikeuskiistat liity tähän sivustoon. Sinun tulee poistaa yllä oleva sisältö kokonaan tietokoneeltasi 24 tunnin kuluessa lataamisesta. Jos pidät ohjelmasta, tue aitoa ohjelmistoa, osta rekisteröityminen ja hanki parempia aitoja palveluita. Jos rikkomuksia ilmenee, ota meihin yhteyttä sähköpostitse.

Mail To:help@itsvse.com