Podívejme se na následující dvě URL, procházejí stejnými parametry? aaa.aspx?tag=.net%bc%BC%ca%f5 aaa.aspx?tag=.net%e6%8a%80%e6%9c%af
Zdá se, že je to jiné, ale ve skutečnosti všechny používají UrlEncode pro ".net technologii", přičemž jeden je kódování GB2312 a druhý kódování Utf-8. Následující kód může dosáhnout výše uvedeného kódovacího efektu:
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);
Naše skutečné webové stránky mohou být vyvolávány jinými programy. Například Chinese Simplified musí stránka ASP v operačním systému předat čínský parametr na ASP.net stránku. Ve výchozím nastavení na čínských zjednodušených operačních systémech bude metoda ASP Server.UrlEncode kódovat čínštinu s kódováním GB2312. Ale ve výchozím nastavení jsou ASP.net stránky kódovány v UTF-8. V tomto případě, když použijete Request.QueryString["Tag"] k přijetí hodnoty, nebudete schopni přijímat čínské informace a při postupném ladění uvidíte zkreslené znaky. V tuto chvíli, i když je Request.QueryString["Tag"] přijímán s nerozešitými znaky, URL v tuto chvíli není zkreslená.
Řešením je analyzovat parametry v URL sami a poté dešifrovat hodnoty parametrů podle kódování GB2312, místo použití výchozího UTF-8 kódování .net. Microsoft dokonce poskytuje odpovídající funkce, takže nemusíme sami používat regulární výrazy k analýze URL řetězců.
Demo kód je následující:
string q = Request.Url.Query;
System.Collections.Specialized.NameValueCollection nv = System.Web.HttpUtility.ParseQueryString(q, System.Text.Encoding.GetEncoding("GB2312")); Response.write(nv["tag"]);
Použijme .NET Reflector od Lutze Roedera k analýze implementace metody System.Web.HttpUtility.ParseQueryString: Pokud se budeme stále vracet, vidíme, že kód, který nakonec zpracovává analýzu řetězců parametrů URL, je následující:
Následující funkce třídy System.Web.HttpValueCollection implementuje parsování parametru URL Zde vidíme, že jde o analýzu prováděnou každou postavou.
- 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);
- }
- }
- }
Kopírovat kód
Co se týče toho, jakou metodu kódování nám druhá strana předá, je nejlepší ji předat jako parametr, abychom ji mohli dešifrovat podle tohoto parametru uživatele. |