Давайте посмотрим на следующие два URL, проходят ли они одни и те же параметры? aaa.aspx?tag=.net%bc%bc%ca%f5 aaa.aspx?tag=.net%e6%8a%80%e6%9c%af
Похоже, что это отличается, но на самом деле все они используют UrlEncode для «.net технологии», но одно — кодирование GB2312, другое — кодирование Utf-8. Следующий код может получить вышеуказанный эффект кодирования:
строка tmp1 = System.Web.HttpUtility.UrlEncode(".net technology", System.Text.Encoding.GetEncoding("GB2312")); строка tmp2 = System.Web.HttpUtility.UrlEncode(".net technology", System.Text.Encoding.UTF8);
Наши официальные веб-страницы могут вызываться другими программами. Например, китайская упрощённая страница ASP в операционной системе должна передавать китайский параметр на страницу ASP.net. По умолчанию на китайских упрощённых операционных системах метод Server.UrlEncode от ASP кодирует китайский язык с кодированием GB2312. Но по умолчанию ASP.net страницы кодируются в UTF-8. В этом случае, когда вы используете Request.QueryString["Tag"] для принятия значения, вы не сможете принять китайскую информацию, и при пошаговой отладке вы увидите искажённые символы. На данный момент, хотя Request.QueryString["Tag"] принимается с искажёнными символами, URL на данный момент не искажен.
Решение — самостоятельно проанализировать параметры в URL, а затем расшифровать значения параметров согласно кодировке GB2312, вместо использования стандартной UTF-8 кодировки .net. На самом деле, Microsoft также предоставляет соответствующие функции, так что нам не нужно использовать регулярные выражения для анализа строк URL самостоятельно.
Демо-код следующий:
строка q = Request.Url.Query;
System.Collections.Specialized.NameValueCollection nv = System.Web.HttpUtility.ParseQueryString(q, System.Text.Encoding.GetEncoding("GB2312")); Response.Write(nv["Tag"]);
Давайте воспользуемся .NET Reflector Lutz Roeder, чтобы рассмотреть реализацию метода System.Web.HttpUtility.ParseQueryString: Если мы продолжаем проверять, то видим, что код, который в итоге обрабатывает анализ строк параметров URL, выглядит следующим образом:
Следующая функция класса System.Web.HttpValueCollection реализует разбор параметра URL Здесь мы видим, что это анализ, проведённый каждым персонажем.
- 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);
- }
- }
- }
Копирование кода
Что касается того, какой метод кодирования нам передаёт другая сторона, лучше передать его как параметр, чтобы мы могли расшифровать его согласно этому параметру пользователя. |