유니 코드 문자를 URL 인코딩하는 올바른 방법은 무엇입니까?


107

비표준 % uxxxx 체계에 대해 알고 있지만 W3C에서 해당 체계를 거부했기 때문에 현명한 선택이 아닌 것 같습니다.

몇 가지 흥미로운 예 :

하트 캐릭터. 내 브라우저에 이것을 입력하면 :

http://www.google.com/search?q=♥

그런 다음 복사하여 붙여 넣으면이 URL이 표시됩니다.

http://www.google.com/search?q=%E2%99%A5

Firefox (또는 Safari)가이 작업을 수행하는 것처럼 보입니다.

urllib.quote_plus(x.encode("latin-1"))
'%E2%99%A5'

3 점 문자처럼 Latin-1로 인코딩 할 수없는 것을 제외하고는 말이됩니다.

URL을 입력하면

http://www.google.com/search?q=…

내 브라우저에 복사하여 붙여 넣으면

http://www.google.com/search?q=%E2%80%A6

뒤. 한 결과 인 것 같습니다.

urllib.quote_plus(x.encode("utf-8"))

… Latin-1로 인코딩 할 수 없기 때문에 의미가 있습니다.

그러나 브라우저가 UTF-8 또는 Latin-1로 디코딩할지 여부를 어떻게 아는지는 분명하지 않습니다.

이것은 모호한 것처럼 보이기 때문에 :

In [67]: u"…".encode('utf-8').decode('latin-1')
Out[67]: u'\xc3\xa2\xc2\x80\xc2\xa6'

작동하므로 브라우저가 UTF-8 또는 Latin-1로 디코딩할지 여부를 어떻게 파악하는지 모르겠습니다.

내가 다루어야 할 특수 문자로 옳은 일은 무엇입니까?


19
두 예제 모두 UTF-8로 인코딩됩니다. 첫 번째는 확실히 Latin-1이 아닙니다. 길이가 3 바이트라는 점을 감안하면 ...
Jakob Borg

2
% E2 % 99 % A5는 UTF-8로 된 "black heart suit" 의 바이트 값에 대한 16 진수입니다 . 그 검은 심장은 Latin-1 문자 집합의 일부가 아닙니다 .
Hawkeye Parker

브라우저가 인코딩하는 방식과 내용 (및 기타 유용한 정보)을 정확하게 확인하려면 대부분의 최신 브라우저에 내장 된 개발자 도구를 사용하거나 Fiddler 와 같은 무료 HTTP 디버거를 사용하세요 .
Hawkeye Parker

답변:


65

항상 UTF-8로 인코딩합니다. 퍼센트 인코딩에 대한 Wikipedia 페이지에서 :

일반 URI 구문은 URI에서 문자 데이터의 표현을 제공하는 새로운 URI 체계가 사실상 번역없이 예약되지 않은 집합의 문자를 나타내야하며 다른 모든 문자를 UTF-8에 따라 바이트로 변환해야한다고 요구합니다. 해당 값을 퍼센트 인코딩합니다. 이 요구 사항은 2005 년 1 월에 소개되었습니다. RFC 3986 . 이 날짜 이전에 도입 된 URI 스킴은 영향을받지 않습니다.

과거에 URL 인코딩을 수행하는 다른 방법이 있었기 때문에 브라우저는 URI를 디코딩하는 여러 가지 방법을 시도하지만 인코딩을 수행하는 경우 UTF-8을 사용해야합니다.


8
UTF-8은 이전 URL 표준을 대체하는 최신 IRI 표준 (RFC 3987, tools.ietf.org/html/rfc3986 )에서 허용하는 유일한 인코딩이기 때문에 사용해야합니다 .
Remy Lebeau

3
다른 사람들이 저처럼 놀란 경우 @RemyLebeau의 댓글에 RFC3987이 언급되어 있지만 링크는 이전 사양 3896에 대한 것입니다. 올바른 URL은 분명히 tools.ietf.org/html/rfc3987
tripleee

네, 죄송합니다. URI는 RFC 3986에 의해 정의되고, IRI는 RFC 3987.에 의해 정의된다
레미 Lebeau

10

일반적인 규칙은 브라우저가 양식이 제공된 페이지의 콘텐츠 유형에 따라 양식 응답을 인코딩하는 것 같습니다. 이것은 서버가 "text / xml; charset = iso-8859-1"을 보내면 동일한 형식으로 응답을 기대한다는 추측입니다.

URL 표시 줄에 URL을 입력하는 경우 브라우저에 작업 할 기본 페이지가 없으므로 추측 만하면됩니다. 따라서이 경우에는 항상 utf-8을 수행하는 것 같습니다 (두 입력이 3 옥텟 형식 값을 생성했기 때문에).

슬픈 사실은 AFAIK가 쿼리 문자열의 값 또는 실제로 URL의 모든 문자를 해석해야하는 문자 집합에 대한 표준이 없다는 것입니다. 적어도 쿼리 문자열의 값의 경우에는 반드시 수행 한다고 가정 할 이유가 없습니다. 문자에 해당합니다.

쿼리 문자열이 인코딩 될 것으로 예상되는 문자 집합을 서버 프레임 워크에 알려야한다는 것은 알려진 문제입니다. 예를 들어 Tomcat에서는 먼저 request.setEncoding () (또는 유사한 메서드)을 호출 해야 합니다. request.getParameter () 메서드를 호출합니다. 이 주제에 대한 문서의 부족은 아마도 많은 개발자들 사이에서 문제에 대한 인식 부족을 반영 할 것입니다. (나는 정기적으로 Java 인터뷰 대상자에게 Reader와 InputStream의 차이점이 무엇인지 묻고 정기적으로 빈 모양을 얻습니다)


6
RFC 3987 ( tools.ietf.org/html/rfc3986 )은 표준 인코딩을 정의합니다. 인코딩되지 않은 상태로 허용되지 않는 문자를 인코딩 할 때는 UTF-8을 사용해야합니다.
Remy Lebeau

8

IRI ( RFC 3987 )는 URI / URL ( RFC 3986 이전) 표준 을 대체하는 최신 표준입니다 . URI / URL은 기본적으로 유니 코드를 지원하지 않습니다 (음, RFC 3986은이 를 지원하기 위해 향후 URI / URL 기반 프로토콜에 대한 조항을 추가하지만 이전 RFC를 업데이트하지는 않습니다). "% uXXXX"체계는 일부 상황에서 유니 코드를 허용하는 비표준 확장이지만 모든 사람이 보편적으로 구현하지는 않습니다. 반면 IRI는 유니 코드를 완벽하게 지원하며 텍스트를 UTF-8로 인코딩 한 다음 퍼센트 인코딩해야합니다.


퍼센트 인코딩뿐만 아니라 URL에서 유니 코드가 완전히 지원되도록 프로토콜에 대한 업데이트를보고 싶습니다.
Mathieu J.

1
IRI는 예약 된 문자를 인코딩해야하는 몇 가지 경우를 제외하고 인코딩되지 않은 유니 코드 문자를 허용합니다.
Remy Lebeau 2015-06-29

6

HTTP를 포함한 일부 컨텍스트에서는 URI (효과적으로 ASCII) 만 허용되기 때문에 IRI는 URI를 대체하지 않습니다.

대신 IRI를 지정하면 유선으로 나갈 때 URI로 변환됩니다.


0

첫 번째 질문은 당신의 필요가 무엇입니까? UTF-8 인코딩은 저렴한 편집기로 만든 텍스트를 가져 오는 것과 다양한 언어를 지원하는 것 사이에서 꽤 좋은 절충안입니다. 인코딩을 식별하는 브라우저와 관련하여 웹 서버의 응답은 브라우저에 인코딩을 알려야합니다. 여전히 대부분의 브라우저는 추측을 시도합니다. 이는 많은 경우에 누락되거나 잘못 되었기 때문입니다. 그들은 기본 인코딩에 맞지 않는 문자가 있는지 확인하기 위해 일정량의 결과 스트림을 읽어 추측합니다. 현재 모든 브라우저 (? 나는 이것을 확인하지 않았지만 사실에 가깝습니다) utf-8을 기본값으로 사용합니다.

따라서 다른 많은 인코딩 체계 중 하나를 사용해야하는 설득력있는 이유가없는 한 utf-8을 사용하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.