Przyjrzyjmy się poniższym dwóm URL-om, czy przechodzą te same parametry? aaa.aspx?tag=.net%bc%bc%ca%f5 aaa.aspx?tag=.net%e6%8a%80%e6%9c%af
Wydaje się, że to inne, ale w rzeczywistości wszystkie używają UrlEncode dla "technologii .net", jednak jedno to kodowanie GB2312, a drugie kodowanie Utf-8. Poniższy kod może uzyskać powyższy efekt kodowania:
string tmp1 = System.Web.HttpUtility.UrlEncode(".net technology", System.Text.Encoding.GetEncoding("GB2312")); string tmp2 = System.Web.HttpUtility.UrlEncode(".net technology", System.Text.Encoding.UTF8);
Nasze rzeczywiste strony mogą być wywoływane przez inne programy. Na przykład w Chinese Simplified strona ASP w systemie operacyjnym musi przekazać parametr chiński do ASP.net strony. Domyślnie, na chińskich uproszczonych systemach operacyjnych, metoda Server.UrlEncode firmy ASP koduje język chiński z kodowaniem GB2312. Ale domyślnie ASP.net strony są kodowane w UTF-8. W takim przypadku, gdy użyjesz Request.QueryString["Tag"], aby zaakceptować wartość, nie będziesz mógł zaakceptować informacji chińskich i zobaczysz zniekształcone znaki podczas debugowania krok po kroku. Obecnie, chociaż Request.QueryString["Tag"] jest akceptowany z zniekształconymi znakami, adres URL nie jest zniekształcony.
Rozwiązaniem jest samodzielna analiza parametrów w URL, a następnie odszyfrowanie wartości parametrów zgodnie z kodowaniem GB2312, zamiast używać domyślnego kodowania UTF-8 w .net. W rzeczywistości Microsoft również dostarcza odpowiadające im funkcje, więc nie musimy sami używać wyrażeń regularnych do analizy ciągów URL.
Kod demonstracyjny przedstawia się następująco:
string q = Request.Url.Query;
System.Collections.Specialized.NameValueCollection nv = System.Web.HttpUtility.ParseQueryString(q, System.Text.Encoding.GetEncoding("GB2312")); Response.write(nv["tag"]);
Skorzystajmy z .NET Reflector Lutza Roedera, aby przyjrzeć się implementacji metody System.Web.HttpUtility.ParseQueryString: Jeśli będziemy sprawdzać wspominanie, zobaczymy, że kod, który ostatecznie obsługuje analizę parametrów URL, wygląda następująco:
Następująca funkcja klasy System.Web.HttpValueCollection implementuje parsowanie parametru URL Tutaj widzimy, że jest to analiza przeprowadzana przez każdą postać.
- internal void FillFromString(string s, bool urlencoded, Encoding encoding)
- {
- int num1 = (s != null) ? s.Length : 0;
- for (int num2 = 0; num2 < num1; num2++)
- {
- int num3 = num2;
- int num4 = -1;
- while (num2 < num1)
- {
- switch (s[num2])
- {
- case ’=’:
- if (num4 < 0)
- {
- num4 = num2;
- }
- break;
- }
- num2++;
- }
- string text1 = null;
- string text2 = null;
- if (num4 >= 0)
- {
- text1 = s.Substring(num3, num4 - num3);
- text2 = s.Substring(num4 + 1, (num2 - num4) - 1);
- }
- else
- {
- text2 = s.Substring(num3, num2 - num3);
- }
- if (urlencoded)
- {
- base.Add(HttpUtility.UrlDecode(text1, encoding), HttpUtility.UrlDecode(text2, encoding));
- }
- else
- {
- base.Add(text1, text2);
- }
- if ((num2 == (num1 - 1)) && (s[num2] == ’&’))
- {
- base.Add(null, string.Empty);
- }
- }
- }
Skopiuj kod
Jeśli chodzi o metodę kodowania, którą przekazuje nam druga strona, najlepiej przekazać ją jako parametr, abyśmy mogli ją odszyfrować zgodnie z tym parametrem użytkownika. |