Heute Morgen wurde ich von einer Kollegin gefragt: Ich sagte, die empfangenen Parameter seien verwirrt, lass mich helfen, das zu lösen.
Die Plattform, für die mein Kollege verantwortlich ist, ist Ext.js Framework aufgebaut, und die web.config-Konfigurationsdatei ist mit der globalen "GB2312"-Codierung konfiguriert:
<Globalization RequestEncoding="gb2312" responseEncoding="gb2312" fileCoding="gb2312" culture="zh-CN"/>
Wenn das Frontend den "chinesischen Text" einreicht, erhält das Backend verzerrte Zeichen mit Request.QueryString["xxx"].
Egal wie man mit System.Web.HttpUtility.UrlDecode("xxx", "encoding type" dekodiert), es funktioniert nicht.
Grundsatzbeschreibung: 1: Das Erste, was festgestellt werden muss, ist, dass Ext.js beim Einreichen der URL-Parameter des Clients vor der Einreichung kodiert, und die Codierung des Clients standardmäßig UTF-8-Codierung ist
2: Warum ist es dann beim Empfang von Parametern mit Request.QueryString["xxx"] verwirrt?
Wir kehren die Kompilierung Schritt für Schritt um, 2.1: Schau dir den Code für die QueryString-Eigenschaft an:
- 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;
- }
- }
Code kopieren
2.2: Schnitt in die FillInQueryStringCollection()-Methode
- 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);
-
- }
- }
Code kopieren
2.3: Cut: 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);
- }
- }
Code kopierenAus dem QueryStringEncoding-Code greift das System standardmäßig auf die Codierungsmethode des Globalisierungskonfigurationsknotens zurück, und wenn nicht, ist standardmäßig die UTF-8-Codierung 2.4: Schnitt in FillFromString (String s, bool urlencodiert, kodierende Codierung)
- 代码有点长,就折叠起来了
- 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);
- }
- }
- }
Code kopierenVon diesem Punkt aus stellen wir fest, dass alle Parametereingaben einmal aufgerufen werden: HttpUtility.UrlDecode(str2, Codierung);
Wenn Client js chinesisch an den Server in der utf-8-Codierung übermittelt, wird er beim Empfang mit Request.QueryString zuerst einmal mit gb2312 dekodiert, das durch Globalisierung konfiguriert ist, was zu verzerrten Zeichen führt.
1: Die JS-Codierungsmethode ist URT-8
2: Die Serverseite hat die Standardeinstellung auf GB2312 konfiguriert
3: Request.QueryString ruft standardmäßig HttpUtility.UrlDecode auf, um die empfangenen Parameter mit Systemkonfigurationskodierung zu dekodieren.
1: Das System wählt die Standardkodierung in folgender Reihenfolge aus: http Request Header – >Globalisierungskonfigurationsknoten – Standard UTF-8
2: Wenn die URL direkt ins Chinesische eingegeben wird, können verschiedene Browser dies unterschiedlich handhaben, zum Beispiel: IE kodiert nicht und reicht sie direkt ein, Firefox reicht die URL nach der GB2312-Codierung ein.
3: Für uncodierte "chinesische Zeichen", nachdem der interne Aufruf Request.QueryString HttpUtility.UrlDecode von gb2312->utf-8 verwendet wurde,
Wenn das chinesische Zeichen nicht gefunden wird, wird es standardmäßig in "%ufffd" umgewandelt, was zu irreversiblen verzerrten Zeichen führt.
4: Der Weg zur Lösung Kennt man das Prinzip, gibt es viele Möglichkeiten, es zu lösen: 1: Die globale Vereinheitlichung ist die UTF-8-Codierung, die Ärger und Sorgen erspart.
2: Wenn GB2312 global angegeben ist, ist die URL chinesisch, und js muss codiert werden, wie ext.js Framework.
So kann man es nur speziell handhaben, indem man die Kodierung und Dekodierung auf der Serverseite spezifiziert. Da das Standardsystem HttpUtility.UrlDecode("xxx", die Codierung der Systemkonfiguration) einmal aufruft, Also ruft man erneut HttpUtility.UrlEncode("xxx", die vom System konfigurierte Codierung auf), um zum ursprünglichen urt-8-Kodierungsparameter zurückzukehren
Dann verwenden Sie HttpUtility.UrlDecode("xxx", utf-8), um es zu dekodieren. String AAA = Anfrage. Request.QueryString["admin"]; Hausbesitzer string a1 = HttpUtility.UrlEncode(aaa, System.Text.Encoding.GetEncoding("GB2312")); string a2 = HttpUtility.UrlDecode(a1,System.Text.Encoding.UTF8);
|