Skip to content
Logo Any Help Me

URL 인코더 / 디코더

설정

URL에 인코딩이 필요한 이유

URL에는 제한된 ASCII 문자만 들어갈 수 있고, 그중 몇몇은 구조적 의미를 지닙니다. ?는 질의 문자열을 시작하고, &는 매개변수를 나누며, /는 경로를 가르고, #은 프래그먼트를 엽니다. 전달하려는 값 안에 그런 문자가 들어 있으면, "이건 데이터"와 "이건 문법"을 구별해 줄 무언가가 필요합니다.

퍼센트 인코딩이 그 장치입니다. 문자를 % 뒤에 그 바이트 값을 16진수로 붙인 형태로 바꿉니다. 공백은 %20, 앰퍼샌드는 %26, 슬래시는 %2F가 됩니다.

문자는 세 부류로 나뉩니다

  • 비예약 문자: 영문자, 숫자, 그리고 - . _ ~. 인코딩이 필요 없고, 해도 합법이지만 의미가 없습니다.
  • 예약 문자: : / ? # [ ] @ ! $ & ' ( ) * + , ; =. 구조적 역할을 맡습니다. 값 안에 들어 있을 때는 인코딩해야 하고, 구조로 쓰일 때는 그대로 두어야 합니다.
  • 그 밖의 전부: 공백, 악센트 문자, 한중일 문자, 이모지. 언제나 인코딩됩니다.

가운데 부류가 이 도구에 모드가 둘인 이유의 전부입니다.

전체 URL이냐 개별 구성요소냐

구성요소 모드는 예약 문자를 인코딩합니다. URL에 들어갈 하나의 값, 검색어, 매개변수, 파일명, 에 쓰세요. 여기에 URL 전체를 넣으면 URL이 망가집니다. URL을 URL로 만들어 주는 ://?&가 전부 인코딩되기 때문입니다.

전체 URL 모드는 문법 문자를 보존하고 문자 그대로 들어갈 수 없는 것만 인코딩합니다. 공백이나 비ASCII 문자가 들어간 완전한 주소에 쓰세요. 다만 매개변수 값 안의 앰퍼샌드는 인코딩하지 않는데, 이는 한계가 아니라 실제 고장 지점입니다.

전형적인 버그가 있습니다. coffee & tea라는 검색어를 전체 URL 모드로 인코딩하면 ?q=coffee%20&%20tea가 되고, 받는 서버는 이를 q=coffee 와 빈 tea라는 두 개의 매개변수로 읽습니다. 각 값을 구성요소 모드로 인코딩한 뒤, 인코딩된 조각들로 URL을 조립하세요.

공백 문제

공백에는 인코딩이 두 가지 있고 서로 바꿔 쓸 수 없습니다. URL 경로에서 공백은 %20입니다. 질의 문자열에서는 오래된 HTML 폼 인코딩이 이를 +로 표현하며, 그러면 진짜 더하기 기호에는 %2B가 필요해집니다.

검색어의 더하기 기호가 이따금 사라지는 이유가 이것입니다. 문자 그대로 전송되었고 받는 쪽이 공백으로 해독한 것이죠. 더하기를 %2B로 퍼센트 인코딩해야 보존됩니다. 요즘 프레임워크는 대개 알아서 처리하지만, 손으로 만든 질의 문자열은 이걸 자주 틀립니다.

유니코드는 먼저 UTF-8을 거칩니다

퍼센트 인코딩은 문자가 아니라 바이트에 작용합니다. 그래서 ASCII 밖의 것은 먼저 UTF-8로 변환되고 나온 바이트마다 따로 인코딩됩니다. 악센트 문자 하나는 두 개의 이스케이프가 되고, 대부분의 한중일 문자는 세 개, 이모지는 네 개가 됩니다.

한글이나 중국어가 든 URL을 인코딩하면 원본보다 훨씬 길어 보이는 이유입니다. 비효율이 아니라 바이트당 이스케이프 하나이고, 그 문자들이 원래 여러 바이트일 뿐입니다.

도메인 이름은 다르게 동작합니다. 퍼센트 인코딩을 담을 수 없으므로 국제화 도메인은 퓨니코드를 써서 비ASCII 이름을 xn--로 시작하는 ASCII 형태로 바꿉니다. 인코딩은 호스트가 아니라 경로와 질의에 적용됩니다.

모든 처리는 표준 encodeURIencodeURIComponent 함수를 써서 브라우저에서 이루어지므로, 붙여넣은 내용은 전송되거나 저장되지 않습니다.

자주 묻는 질문

두 모드는 무엇이 다른가요?
구성요소 모드는 ?나 & 같은 예약 문자까지 인코딩해 개별 값에 적합합니다. 전체 URL 모드는 그것들을 보존해 완전한 주소가 유효하게 남습니다.
인코딩했더니 URL이 왜 깨졌나요?
URL 전체를 구성요소 모드로 인코딩했을 가능성이 큽니다. URL을 URL로 만드는 ://와 ?까지 인코딩되기 때문입니다. 값마다 따로 인코딩한 뒤 조립하세요.
%20이 왜 가끔 +로 나오나요?
공백의 인코딩이 둘이기 때문입니다. 경로에서는 %20, 질의 문자열의 오래된 폼 인코딩에서는 +를 쓰며, 그래서 진짜 더하기는 %2B가 되어야 합니다.
한글을 인코딩하면 왜 이렇게 길어지나요?
퍼센트 인코딩이 바이트 단위로 작동하기 때문입니다. 한글은 UTF-8에서 3바이트라 문자마다 이스케이프가 세 개 생깁니다.
인코딩이 전혀 필요 없는 문자는?
영문자, 숫자, 그리고 비예약 기호 네 개(- . _ ~)입니다. 인코딩해도 되지만 얻는 것이 없습니다.
한글 도메인은 어떻게 처리되나요?
퍼센트 인코딩이 아니라 퓨니코드로 처리되어 xn--로 시작하는 ASCII 형태가 됩니다. 인코딩은 경로와 질의에만 적용됩니다.
제 데이터가 전송되나요?
아니요. 인코딩과 디코딩 모두 브라우저에서 이루어지며 붙여넣은 내용은 전송되거나 저장되지 않습니다.

더 많은 도구 보기: 개발자

모두 보기 →