EscapeUriString과 EscapeDataString의 차이점은 무엇입니까?


195

URL 인코딩 만 다루는 경우 사용해야합니다. EscapeUriString ?


10
@Livven의 답변에 설명 된대로 항상을 사용하여 각 개별 을 피하십시오 Uri.EscapeDataString(). 다른 접근 방식을 사용하면 시스템에는 가능한 모든 입력에 대해 의도 한 결과를 생성하기에 충분한 정보가 없습니다.
Timo

답변:


112

EscapeDataString항상 사용 (이유에 대한 자세한 내용은 아래 Livven의 답변 참조)

편집 : 인코딩에서 두 가지가 다른 데드 링크 제거


3
링크가 실제로 이스케이프 처리보다 이스케이프 처리에 관한 더 많은 정보를 제공하는지 확실하지 않습니다.
Steven

1
기본적으로 같은 차이입니다. 실제로 기사를 읽으면 중간에 실제로 이스케이프 처리 (이스케이프 처리 안함)되어 차이를 표시하는 테이블이 있습니다 (비교 URLEncode도 마찬가지입니다).
Jcl

2
전체 URI를 이스케이프 처리하지 않고 일부만 처리하는 경우 (예 : 쿼리 문자열 매개 변수에 대한 데이터) 여전히 명확하지 않습니다 . URI의 데이터를 이스케이프 처리합니까, 아니면 EscapeDataString이 완전히 다른 것을 의미합니까?
BrainSlugs83

4
... 일부 테스트는 URI 매개 변수에 대해 EscapeDataString을 원하는 것처럼 보입니다. "I heart C ++"라는 문자열로 테스트했으며 EscapeUriString은 "+"문자를 인코딩하지 않았습니다. EscapeDataString은 그대로 "% 2B"(으)로 변환했습니다.
BrainSlugs83

7
이것은 나쁜 대답입니다. EscapeUriString을 절대 사용해서는 안되며 의미가 없습니다. 아래의 Livven의 답변을 참조하십시오.
Brandon Paddock

243

기존 답변이 만족스럽지 않아이 문제를 해결하기 위해 조금 더 깊이 파기로 결정했습니다. 놀랍게도 그 대답은 매우 간단합니다.

사용할 거의 이유가 없습니다 (거의 *) Uri.EscapeUriString. 문자열을 퍼센트 인코딩해야하는 경우 항상을 사용하십시오 Uri.EscapeDataString.

* 유효한 사용 사례는 마지막 단락을 참조하십시오.

왜 이런거야? 설명서 에 따르면 :

EscapeUriString 메소드를 사용하여 이스케이프 처리되지 않은 URI 문자열을 Uri 생성자에 대한 매개 변수로 준비하십시오.

이것은 실제로 이해가되지 않습니다. RFC 2396 에 따르면 :

완성 된 URI를 이스케이프하거나 이스케이프 처리하면 의미가 변경 될 수 있으므로 URI는 항상 "이스케이프 된"형식입니다.

인용 된 RFC는 RFC 3986에 의해 폐기되었지만 , 요점은 여전히 ​​유효합니다. 구체적인 예를 살펴보면이를 확인하겠습니다.

  1. 다음과 같은 간단한 URI가 있습니다.

    http://example.org/

    Uri.EscapeUriString 변경하지 않습니다.

  2. 이스케이프를 고려하지 않고 쿼리 문자열을 수동으로 편집하기로 결정했습니다.

    http://example.org/?key=two words

    Uri.EscapeUriString 당신을 위해 공간을 (올바르게) 벗어날 것입니다 :

    http://example.org/?key=two%20words
  3. 쿼리 문자열을 수동으로 더 편집하기로 결정합니다.

    http://example.org/?parameter=father&son

    그러나이 문자열은 Uri.EscapeUriString앰퍼샌드가 다른 키-값 쌍의 시작을 의미한다고 가정하기 때문에에 의해 변경되지 않습니다 . 이것은 당신이 의도 한 것일 수도 아닐 수도 있습니다.

  4. 실제로 key매개 변수를 원하는 것으로 결정 father&son하면 앰퍼샌드를 이스케이프 처리하여 이전 URL을 수동으로 수정하십시오.

    http://example.org/?parameter=father%26son

    그러나 Uri.EscapeUriString퍼센트 문자도 이스케이프되어 이중 인코딩으로 이어집니다.

    http://example.org/?parameter=father%2526son

보다시피 Uri.EscapeUriString의도 된 용도로 사용 &하면 여러 키-값 쌍 사이의 구분 기호 대신 쿼리 문자열에서 키 또는 값의 일부로 사용할 수 없습니다 .

이는 전체 URI를 이스케이프 처리하기 위해 예약 된 문자를 무시하고 예약되거나 예약되지 않은 문자 만 이스케이프하기 때문에 BTW는 문서와 반대이기 때문 입니다. 이렇게하면와 같은 것으로 http%3A%2F%2Fexample.org%2F끝나지 않지만 위에서 설명한 문제로 끝납니다.


결국 URI가 유효하면 매개 변수로 Uri construtor에 전달하기 위해 이스케이프 할 필요가 없으며 유효하지 않은 경우 호출 Uri.EscapeUriString도 마법 솔루션이 아닙니다. 실제로 대부분의 경우는 아니지만 대부분의 경우 작동하지만 결코 신뢰할 수는 없습니다.

키-값 쌍과 퍼센트 인코딩을 수집 한 다음 필요한 구분 기호로 연결하여 항상 URL과 쿼리 문자열을 구성해야합니다. 위에서 언급 한 것처럼 예약 된 문자를 이스케이프하지 않으므로이 Uri.EscapeDataString용도로 는 사용할 수 있지만 사용할 수 Uri.EscapeUriString는 없습니다.

예를 들어 사용자 제공 URI를 처리 할 때이를 수행 할 수없는 경우에만 Uri.EscapeUriString최후의 수단 으로 사용 하는 것이 좋습니다. 그러나 앞에서 언급 한 경고가 적용됩니다. 사용자 제공 URI가 모호한 경우 결과가 바람직하지 않을 수 있습니다.


4
와우,이 문제를 명확히 해주셔서 감사합니다. 이전 두 답변은별로 도움이되지 않았습니다.
EverPresent

3
정확히 맞습니다. EscapeUriString (Win32에서 EscapeUrl의 기본 동작)은 URI를 이해하지 못하거나 이스케이프 처리하지 않은 사람이 작성했습니다. 잘못된 형식의 URI를 사용하여 때로는 의도 한 버전으로 바꾸는 무언가를 만들려는 잘못된 시도 입니다. 그러나이를 안정적으로 수행하는 데 필요한 정보는 없습니다. 또한 매우 문제가되는 EscapeDataString 대신 자주 사용됩니다. EscapeUriString이 존재하지 않기를 바랍니다. 그것을 사용할 때마다 잘못되었습니다.
Brandon Paddock

4
잘 설명 +1 그것은 허용 된 링크 전용 답변보다 낫다
Ehsan Sajjad

1
이 답변에는 더 많은주의가 필요합니다. 올바른 방법입니다. 다른 답변에는 의도 한 결과를 얻지 못하는 시나리오가 있습니다.
Timo

1
... 물론이 encodeURI/ Uri.EscapeUriString로 필요하지 않습니다 자주 encodeURIComponent/ Uri.EscapeDataString(당신이 URI 맥락에서 사용되어야 블라인드의 URL을 deaing 때부터),하지만 그 뜻은 아닙니다 그것의 장소를 가지고 있지 않습니다.
초승달 신선한

56

더하기 (+) 문자는 이러한 방법의 차이점에 대해 많은 것을 알 수 있습니다. 간단한 URI에서 더하기 문자는 "공백"을 의미합니다. "행복한 고양이"에 대해 Google에 문의 해보십시오.

https://www.google.com/?q=happy+cat

유효한 URI (시도)이며 EscapeUriString수정하지 않습니다.

이제 "happy c ++"에 대해 Google에 문의 해보십시오.

https://www.google.com/?q=happy+c++

그것은 유효한 URI (시도)이지만 두 개의 플러스는 공백으로 해석되기 때문에 "happy c"를 검색합니다. 이 문제를 해결하기 위해 "happy c ++"를 EscapeDataStringvoila *로 전달할 수 있습니다 .

https://www.google.com/?q=happy+c%2B%2B

*) 인코딩 된 데이터 문자열은 실제로 "happy % 20c % 2B % 2B"입니다. 공백 문자는 % 20이 16 진수이고 더하기 문자는 % 2B가 16 진수입니다.

원하는 UriBuilder대로 사용 하는 경우 EscapeDataString전체 URI의 일부 구성 요소 만 올바르게 이스케이프하면됩니다. 이 질문에 대한 @Livven의 답변은 실제로 사용할 이유가 없다는 것을 증명합니다 EscapeUriString.


감사. 당신은 예를 들어, 인코딩해야하는 절대 URI 문자열이있는 경우는 어떨까요 "https://www.google.com/?q=happy c++". "?"에서 수동으로 분할해야합니까, 아니면 더 좋은 방법이 있습니까?
wensveen

전체 URL을 매개 변수로 다른 URL에 전달하는 경우을 사용하십시오 EscapeDataString. 제공 한 URL이 실제 URL 인 경우으로 분할하려고합니다 ?.
세스

7

소스의 주석은 차이점을 명확하게 해결합니다. 이 정보가 XML 문서 주석을 통해 전달되지 않는 이유는 미스터리입니다.

EscapeUriString :

이 방법은 퍼센트 부호를 포함하여 예약되거나 예약되지 않은 문자를 피합니다. EscapeUriString은 '#'부호도 이스케이프하지 않습니다.

EscapeDataString :

이 방법은 퍼센트 부호를 포함하여 예약되지 않은 문자가 아닌 모든 문자를 이스케이프합니다.

차이점은 예약 문자 를 처리하는 방법에 있습니다 . EscapeDataString그들을 탈출; EscapeUriString하지 않습니다.

RFC 에 따르면 예약 문자는 다음과 같습니다.:/?#[]@!$&'()*+,;=

완전성을 위해 예약되지 않은 문자는 영숫자 및 -._~

두 방법 모두 예약되거나 예약되지 않은 문자를 이스케이프합니다.

나는 일반에 동의 개념EscapeUriString 악이다. 공백과 같은 잘못된 문자 만 이스케이프 하고 예약 문자가 아닌 방법 이 유용하다고 생각합니다. 그러나 %캐릭터를 다루는 방법에는 문제가 있습니다. 인코딩 된 문자 ( %2 진수 16 진수)는 URI에서 유효 합니다. EscapeUriString이 패턴을 감지 %하고 2 진수로 즉시 진행되면 인코딩을 피하면 훨씬 더 유용 할 것이라고 생각 합니다 .


1

간단한 예

var data = "example.com/abc?DEF=あいう\x20えお";

Console.WriteLine(Uri.EscapeUriString(data));
Console.WriteLine(Uri.EscapeDataString(data));
Console.WriteLine(System.Net.WebUtility.UrlEncode(data));
Console.WriteLine(System.Web.HttpUtility.UrlEncode(data));

/*
=>
example.com/abc?DEF=%E3%81%82%E3%81%84%E3%81%86%20%E3%81%88%E3%81%8A
example.com%2Fabc%3FDEF%3D%E3%81%82%E3%81%84%E3%81%86%20%E3%81%88%E3%81%8A
example.com%2Fabc%3FDEF%3D%E3%81%82%E3%81%84%E3%81%86+%E3%81%88%E3%81%8A
example.com%2fabc%3fDEF%3d%e3%81%82%e3%81%84%e3%81%86+%e3%81%88%e3%81%8a
*/
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.