URL 인코드 / 디코드
URL 컴포넌트와 쿼리 문자열을 즉시 인코딩·디코딩합니다. 무료, 브라우저에서 처리.
- 브라우저에서 처리
- 데이터가 브라우저 밖으로 나가지 않습니다
- 무료 · 회원가입 불필요
WeChat으로 스캔하여 공유
예시·자세한 설명·자주 묻는 질문 실제 출력이 있는 예시, 다른 도구와의 차이, 자주 묻는 질문.
검색어를 쿼리 값으로 넣을 때
?q= 뒤에 검색어를 붙이기 전에 검색어를 하나의 ‘값’으로 인코딩해야 합니다. 그대로 두면 공백이나 &, =가 URL의 구분자로 읽힙니다.
서울 맛집 (강남)을 기본 설정으로 인코딩하면 %EC%84%9C%EC%9A%B8%20%EB%A7%9B%EC%A7%91%20(%EA%B0%95%EB%82%A8)이 됩니다. 한글 한 음절은 %XX 세 개, 공백은 %20이고, 괄호는 인코딩되지 않고 그대로 남습니다.
공백을 +로 (폼 데이터)를 켜면 같은 입력이 %EC%84%9C%EC%9A%B8+%EB%A7%9B%EC%A7%91+%28%EA%B0%95%EB%82%A8%29가 됩니다. 공백은 +로 바뀌고, 이번에는 괄호도 %28, %29로 인코딩됩니다. 브라우저의 폼 전송이나 URLSearchParams가 만드는 형식과 같습니다. 서명 값을 비교하는 API라면 상대가 어느 형식으로 계산하는지 먼저 확인하세요.
EUC-KR로 만들어진 오래된 주소
HTML 폼은 페이지 자체의 문자 인코딩으로 쿼리를 인코딩합니다(HTML Living Standard 4.10.22.5: 먼저 문서의 문자 인코딩을 사용). 그래서 EUC-KR로 작성된 페이지에서 전송된 ‘서울’은 UTF-8의 %EC%84%9C%EC%9A%B8이 아니라 %BC%AD%BF%EF가 됩니다.
이 값을 디코딩하면 깨진 글자를 보여 주는 대신 1번째 문자부터: %BC%AD%BF%EF은(는) 올바른 UTF-8이 아닙니다. EUC-KR 등 다른 인코딩의 텍스트는 여기서 디코딩할 수 없습니다.라고 표시하고 멈춥니다. EUC-KR은 WHATWG Encoding Standard에서 레거시 인코딩으로 분류되며, 읽으려면 인코딩을 지정할 수 있는 처리가 필요합니다. 예를 들어 Python에서는 urllib.parse.unquote('%BC%AD%BF%EF', encoding='euc-kr')로 서울을 얻습니다.
두 번 인코딩된 값
주소에 %25가 보이면 이미 인코딩된 값을 한 번 더 인코딩했을 가능성이 큽니다. % 자체가 %25로 바뀌기 때문입니다. 예를 들어 a b는 a%20b가 되고, 한 번 더 인코딩하면 a%2520b가 됩니다. 이런 값을 디코딩 칸에 넣고 한 번 풀면 직전 단계가 보이므로, 어느 단계에서 인코딩이 중복됐는지 거슬러 올라가 확인할 수 있습니다.
이 도구를 쓰기 좋은 경우
- 쿼리 값에 공백,
&,=,#, 한글이 들어갈 때. - 주소 전체를 다른 주소의 파라미터로 넘길 때(로그인 후 돌아갈 주소 등).
:와/도 인코딩되므로 하나의 값으로 전달됩니다. - 바로 열어 볼 완전한 주소를 정리하는 용도에는 맞지 않습니다. 구분자까지 인코딩되어 링크로 쓸 수 없게 됩니다. 이때는 URL 파서에서 파라미터를 하나씩 고치세요.
제한 사항
- UTF-8만 지원하며 인코딩을 추측하지 않습니다. EUC-KR, CP949 등으로 만든 퍼센트 인코딩은 대부분 오류가 나지만, 바이트가 우연히 올바른 UTF-8이면 다른 글자로 바뀌어 표시되고 경고도 없습니다. 예를 들어 EUC-KR의 ‘홍’은
%C8%AB인데, 디코딩하면ȫ가 됩니다. - 디코딩은 첫 번째 문제에서 멈추고 위치를 알려 줍니다. 끝에 홀로 있는
100%의%도 오류입니다. - 기본 인코딩은
! ' ( ) *를 그대로 둡니다(encodeURIComponent의 규칙). 서명 계산 등에서%21 %27 %28 %29 %2A가 필요하면 직접 바꿔야 합니다. encodeURI모드는 없습니다.- 이모지 중간이 잘린 문자열(짝이 없는 서로게이트)은 인코딩할 수 없으며 위치를 표시합니다.
FAQ
URL 인코딩이란 무엇입니까?
URL 인코딩(퍼센트 인코딩, RFC 3986 2.1절)은 문자의 UTF-8 바이트를 하나씩 %와 16진수 두 자리로 쓰는 방식입니다. 공백은 %20, &는 %26이 되고, 한글 음절은 3바이트이므로 '한'은 %ED%95%9C가 됩니다.
encodeURI와 encodeURIComponent의 차이는 무엇입니까?
encodeURI는 URL 전체를 대상으로 하며 ; , / ? : @ & = + $ # 같은 구분자를 그대로 둡니다. encodeURIComponent는 쿼리 값처럼 URL의 한 부분을 대상으로 하며 이 구분자들도 인코딩합니다. 영문자, 숫자와 - _ . ! ~ * ' ( )는 둘 다 인코딩하지 않습니다. [와 ]는 encodeURI에서도 %5B, %5D가 됩니다. 이 도구는 encodeURIComponent를 사용합니다.
디코딩해도 +가 남는 이유는 무엇입니까?
decodeURIComponent는 %XX만 되돌립니다. 공백을 +로 쓰는 것은 HTML 폼 형식(application/x-www-form-urlencoded)의 규칙이고 퍼센트 인코딩의 규칙이 아니므로, 기본 설정에서는 a+b가 그대로 a+b입니다. 공백을 +로 (폼 데이터)를 켜면 URLSearchParams처럼 +를 공백으로 읽습니다.
디코딩에 실패하는 이유는 무엇입니까?
% 뒤에 16진수 두 자리가 없거나(100%, %zz), 바이트가 올바른 UTF-8이 아닌 경우입니다. 중간에 잘린 %E4%B8이나 EUC-KR로 만든 %BC%AD가 후자에 해당합니다. 상태 줄에 위치와 문제가 된 부분이 표시됩니다.
EUC-KR로 만든 옛 주소는 어떻게 읽나요?
이 도구는 UTF-8만 읽기 때문에 EUC-KR로 인코딩된 '서울'(%BC%AD%BF%EF)은 1번째 문자부터 올바른 UTF-8이 아니라는 오류가 납니다. 인코딩을 지정할 수 있는 프로그램을 쓰세요. 예를 들어 Python의 urllib.parse.unquote('%BC%AD%BF%EF', encoding='euc-kr')는 서울을 돌려줍니다. 같은 글자를 UTF-8로 쓰면 %EC%84%9C%EC%9A%B8입니다.
데이터가 서버로 전송됩니까?
아니요. 변환은 브라우저 안에서 처리되며 결과는 JavaScript 내장 함수 encodeURIComponent / decodeURIComponent와 같습니다. 마지막 입력은 다음에 열 때 복원하도록 이 브라우저의 로컬 저장소에 저장되며, 지우기를 누르면 삭제됩니다.