다음 두 URL을 살펴보겠습니다. 두 URL이 동일한 매개변수를 통과하나요? aaa.aspx?tag=.net%bc%bc%ca%f5 aaa.aspx?tag=.net%e6%8a%80%e6%9c%af
겉보기에는 다를 수 있지만, 사실 모두 ".net 기술"을 위해 UrlEncode를 사용하는데, 하나는 GB2312 인코딩이고 다른 하나는 Utf-8 인코딩입니다. 다음 코드는 위의 인코딩 효과를 얻을 수 있습니다:
string tmp1 = System.Web.HttpUtility.UrlEncode(".net technology", System.Text.Encoding.GetEncoding("GB2312")); string tmp2 = System.Web.HttpUtility.UrlEncode(".net 기술", System.Text.Encoding.UTF8);
저희 웹사이트는 다른 프로그램에서 호출될 수 있습니다. 예를 들어, 운영체제의 ASP 페이지는 중국어 간체체를 ASP.net 페이지에 전달해야 합니다. 기본적으로 중국어 간체 운영체제에서는 ASP의 Server.UrlEncode 메서드가 중국어를 GB2312 인코딩으로 인코딩합니다. 하지만 기본적으로 ASP.net 페이지는 UTF-8로 인코딩되어 있습니다. 이 경우 Request.QueryString["Tag"]를 사용해 값을 받아들이면 중국어 정보를 받을 수 없고, 단계별 디버깅에서 왜곡된 문자가 보일 수 있습니다. 현재 Request.QueryString["Tag"]는 왜곡된 문자로 받아들여지지만, URL은 현재 오류가 없습니다.
해결책은 URL의 매개변수를 직접 분석한 후, .net의 기본 UTF-8 인코딩 대신 GB2312 인코딩에 따라 매개변수 값을 복호화하는 것입니다. 사실 마이크로소프트도 이에 대응하는 함수를 제공하므로, 우리가 직접 정규 표현식을 사용하지 않아도 URL 문자열을 분석할 수 있습니다.
데모 코드는 다음과 같습니다:
string q = Request.Url.Query;
System.Collections.Specialized.NameValueCollection nv = System.Web.HttpUtility.ParseQueryString(q, System.Text.Encoding.GetEncoding("GB2312")); Response.Write(nv["태그"]);
Lutz Roeder의 .NET Reflector를 사용해 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);
- }
- }
- }
코드 복사
상대방이 우리에게 어떤 인코딩 방식을 전달하는지는 매개변수로 전달하는 것이 가장 좋습니다. 그래야 사용자의 이 매개변수에 따라 복호화할 수 있습니다. |