URL 인코딩 / 디코딩

URL과 쿼리 문자열 값을 퍼센트 인코딩하거나 디코딩합니다. 한글 주소도 변환되고, URL의 쿼리 매개변수를 읽기 쉬운 표로 보여 줍니다.

URL 인코더·디코더 사용법

  1. 텍스트를 URL에 안전하게 넣으려면 인코딩을, 퍼센트 인코딩된 텍스트를 읽을 수 있는 글자로 되돌리려면 디코딩을 고릅니다.
  2. 위쪽 칸에 입력하거나 붙여 넣습니다. 한 글자 입력할 때마다 결과가 바로 바뀌므로 따로 누를 버튼이 없습니다.
  3. 인코딩 모드에서는 값 하나가 아니라 주소 전체를 붙여 넣었다면 URL 전체 인코딩을, 결과를 폼 방식의 쿼리 문자열에 넣을 것이라면 공백을 +로 인코딩을 켭니다.
  4. 디코딩 모드에서는 +를 공백으로 디코딩이 기본으로 켜져 있습니다. 텍스트 속 더하기 기호가 진짜 +라면 끕니다.
  5. 복사를 누르거나, ⇅ 서로 바꾸기로 결과를 입력 칸에 옮기고 모드를 뒤집습니다. 값을 인코딩했다가 디코딩해도 원래대로 돌아오는지 빠르게 확인할 수 있습니다.

입력한 내용이 http:// 또는 https://로 시작하는 완전한 주소이면 URL 구성 요소 표가 나타나 프로토콜, 호스트, 디코딩된 경로, 쿼리 매개변수(한 줄에 하나씩), # 뒤의 프래그먼트를 보여 줍니다. 길게 늘어진 추적 링크나 누군가 보내 준 API 요청 주소를 읽을 때 가장 빠른 방법입니다.

퍼센트 인코딩이란

URL 문법을 정한 표준인 RFC 3986은 아주 적은 수의 ASCII 문자만 그대로 쓰도록 허용합니다. 영문자, 숫자, - . _ ~는 ‘비예약 문자’라서 인코딩할 필요가 없습니다. : / ? # [ ] @ ! $ & ' ( ) * + , ; = 같은 문자는 ‘예약 문자’로, URL의 각 부분을 나누는 역할을 하므로 값 안에 들어갈 때는 인코딩해야 합니다. 그 밖의 모든 문자, 즉 공백, 따옴표, 악센트가 붙은 글자, 한글·일본어·중국어, 이모지는 언제나 인코딩됩니다.

인코딩은 글자가 아니라 바이트 단위로 이루어집니다. 텍스트를 먼저 UTF-8로 바꾼 뒤, 이스케이프가 필요한 바이트마다 %와 16진수 두 자리를 씁니다. 그래서 글자 하나가 여러 개의 이스케이프로 바뀌기도 합니다. é는 2바이트(%C3%A9), 한글·한자·가나는 대부분 3바이트(서는 %EC%84%9C), 👍 같은 이모지는 4바이트(%F0%9F%91%8D)입니다.

세 가지 옵션

  • 기본은 JavaScript의 encodeURIComponent를 씁니다. 영문자, 숫자, - _ . ! ~ * ' ( )를 뺀 모든 문자를 이스케이프하므로 &, =, /, ?, +도 모두 인코딩됩니다. 검색어, 매개변수 값, 경로 속 파일 이름처럼 URL의 한 조각에 씁니다.
  • URL 전체 인코딩은 encodeURI로 바꿉니다. 예약 문자를 건드리지 않아 주소의 구조가 유지됩니다. 공백이나 한글이 섞인 링크를 정리할 때 씁니다.
  • 공백을 +로 인코딩은 모든 %20을 +로 바꿉니다. HTML 폼 전송(application/x-www-form-urlencoded)의 관례입니다. 기본 모드에서는 원래 텍스트에 있던 더하기 기호가 %2B로 바뀌므로 공백과 헷갈리지 않습니다.

예시

입력설정결과
café & croissants기본caf%C3%A9%20%26%20croissants
café & croissants공백을 +로caf%C3%A9+%26+croissants
서울 맛집기본%EC%84%9C%EC%9A%B8%20%EB%A7%9B%EC%A7%91
a+b=c기본a%2Bb%3Dc
50% off기본50%25%20off
https://example.com/search?q=naïve café&lang=frURL 전체https://example.com/search?q=na%C3%AFve%20caf%C3%A9&lang=fr

URL 전체 인코딩은 값 안에 이미 예약 문자가 들어 있는 주소를 고쳐 주지 못합니다. https://example.com/search?q=rock & roll&page=2를 이 방식으로 인코딩하면 q=rock%20&%20roll이 되고, 서버는 q를 “rock ”으로만 읽습니다. 값만 따로 기본 모드로 인코딩해 rock%20%26%20roll을 만든 뒤 주소에 넣어야 합니다.

자주 하는 실수

  • 이중 인코딩. 이미 인코딩된 텍스트를 다시 인코딩하면 모든 %가 %25로 바뀌어 %20이 %2520이 됩니다. 링크에 %25 뒤로 16진수 두 자리가 이어진다면 어딘가에서 두 번 인코딩한 것입니다. 한 번 디코딩한 뒤 다시 확인하세요.
  • 그대로 남아야 할 + 기호. 쿼리 문자열에서 +는 보통 공백을 뜻하지만, 경로나 encodeURIComponent로 만든 데이터에서는 진짜 더하기일 수 있습니다. +82… 같은 전화번호가 디코딩 뒤 +를 잃는다면 + 옵션을 끄세요.
  • 예전 문자 인코딩. 오래된 시스템 중에는 UTF-8 대신 EUC-KR, Latin-1, Shift_JIS 바이트를 인코딩해 caf%E9 같은 결과를 내는 곳이 있습니다. 이런 바이트는 올바른 UTF-8이 아니므로 디코더는 추측하지 않고 오류를 표시합니다.
  • HTML 이스케이프가 필요한 곳에 URL 인코딩 쓰기. 퍼센트 인코딩은 텍스트를 URL 안에서 안전하게 만들 뿐, 웹 페이지 안에서는 아닙니다. HTML에 <나 &를 표시하려면 HTML 엔티티 변환기를 쓰세요. 바이너리 데이터를 URL에 넣을 때는 URL-safe Base64가 대개 더 알맞습니다.

자주 묻는 질문

디코딩할 때 왜 오류가 나나요?

입력에 16진수 두 자리가 뒤따르지 않는 %가 있거나(100%처럼), 여러 바이트로 된 문자가 중간에 잘렸기 때문입니다. 예를 들어 %E2%82는 마지막 %AC가 있어야 €가 됩니다. 문자열 전체를 복사했는지 확인하세요. 할인율처럼 단순히 퍼센트 기호가 들어 있는 텍스트는 애초에 인코딩된 적이 없으니 디코딩하지 않아도 됩니다.

공백은 %20인가요, +인가요?

URL의 쿼리 부분에서는 폼 데이터를 읽는 서버가 둘 다 공백으로 처리합니다. 경로에서는 %20만 맞습니다. /my+file.pdf는 이름에 +가 들어간 파일을 가리킵니다. 확실하지 않으면 %20을 쓰세요. 모든 서버가 이해합니다.

링크 속 한글도 인코딩해야 하나요?

브라우저 주소창에는 한글이 그대로 보이지만, 실제로는 퍼센트 인코딩된 바이트가 전송됩니다. 이런 URL을 코드, HTTP 헤더, 이메일 템플릿, 사이트맵에 넣을 때는 인코딩해 두어야 어떤 시스템이든 같은 주소로 읽습니다.

한글 도메인은 어떻게 하나요?

호스트 이름은 퓨니코드(Punycode)라는 별도의 방식을 씁니다. DNS에서는 한글.kr이 xn--bj0bj06e.kr로 바뀌는 식입니다. 퍼센트 인코딩은 경로, 쿼리 문자열, 프래그먼트를 위한 것입니다.