본문으로 건너뛰기
소이툴즈

URL 인코더 · 디코더

URL을 인코딩·디코딩하고 쿼리 파라미터를 표로 쪼개 봅니다. 인코딩 방식 세 가지의 차이도 함께 확인할 수 있습니다.

encodeURIComponent — 쿼리 값 하나를 감쌀 때. / ? & = 까지 전부 인코딩합니다.

URL 구성 요소

  • 프로토콜https
  • 호스트so-yi.com
  • 포트(기본값)
  • 경로/calc/salary
  • 프래그먼트(없음)

쿼리 파라미터 1개 (디코딩된 값)

  • 연봉5000만

세 가지 인코딩 방식

URL 인코딩은 하나가 아닙니다. 쓰는 위치에 따라 세 가지가 있고, 잘못 고르면 값이 깨집니다.

값 하나를 감쌀 때 (encodeURIComponent)

쿼리 파라미터의 값 하나를 넣을 때 씁니다. /, ?, &, =, #까지 전부 인코딩합니다.

값 안에 &나 =가 들어 있어도 파라미터가 잘못 쪼개지지 않습니다. 파라미터 값에는 반드시 이 방식을 써야 합니다.

URL 전체를 넘길 때 (encodeURI)

주소 전체를 인코딩하되 구조 문자는 그대로 둡니다. 그래서 URL이 URL로서 유효하게 남습니다. 한글 경로가 포함된 주소를 통째로 인코딩할 때 씁니다.

폼 전송 (x-www-form-urlencoded)

HTML 폼이 GET으로 전송할 때 쓰는 방식입니다. 다른 방식과 딱 하나 다릅니다. 공백을 %20이 아니라 +로 바꿉니다.

도구 사용법

방향에서 인코딩과 디코딩을 고르고, 인코딩 방식에서 값 하나·URL 전체·폼 전송 중 하나를 고릅니다. 어느 방식이 맞는지 모르겠다면 값 하나가 기본입니다. 파라미터 값을 다루는 상황이 압도적으로 많기 때문입니다.

디코딩 모드에서 완전한 URL을 넣으면 아래에 URL 구성 요소 표가 함께 나옵니다. 프로토콜, 호스트, 포트, 경로, 프래그먼트와 쿼리 파라미터를 하나씩 풀어 보여 주므로, 긴 추적 링크에 어떤 값이 실려 있는지 확인할 때 씁니다.

디코딩할 문자열에 %E0처럼 뒤가 잘린 퍼센트 시퀀스가 있으면 브라우저가 디코딩을 거부합니다. 이 도구는 그 경우 어디가 문제인지 알려 주는 안내를 띄웁니다. 복사하다 잘린 URL에서 자주 생기는 일이라, 원본을 다시 복사해 오는 것이 해결책입니다.

자주 쓰는 문자의 인코딩 값

| 문자 | 인코딩 | 문자 | 인코딩 | | ---- | ------ | ---- | ------ | | 공백 | %20 | & | %26 | | # | %23 | + | %2B | | % | %25 | / | %2F | | = | %3D | ? | %3F | | @ | %40 | : | %3A |

URL에서 ?, &, =, #은 각각 쿼리 시작, 파라미터 구분, 키와 값 구분, 프래그먼트 시작이라는 역할이 있습니다. 값 안에 이 문자가 글자로 들어가야 한다면 반드시 인코딩해야 구조가 깨지지 않습니다. 검색어에 C&D를 넣었는데 C만 검색된다면 &가 인코딩되지 않은 것입니다.

공백이 %20이 되기도 +가 되기도 하는 이유

| 위치 | 공백 표현 | |---|---| | URL 경로 | %20 | | 일반 쿼리스트링 | %20 | | HTML 폼 전송 | + |

문제는 두 방식이 섞일 때입니다. +로 인코딩된 값을 decodeURIComponent로 풀면 +가 공백이 아니라 진짜 더하기 기호로 남습니다. 반대로 진짜 +가 들어 있는 값(예: 전화번호 +82-10-...)을 폼 방식으로 디코딩하면 공백이 되어 버립니다.

이 도구에서 방식을 바꿔 가며 결과를 비교해 보면 차이가 바로 보입니다.

한글 주소가 길어지는 이유

URL은 ASCII만 담을 수 있습니다. 그래서 한글은 먼저 UTF-8 바이트로 바뀌고, 각 바이트가 %XX 형태로 표현됩니다.

한글 한 글자는 UTF-8에서 3바이트이므로 한 → %ED%95%9C으로 9자가 됩니다. 열 글자짜리 한글 검색어는 90자로 불어납니다.

브라우저 주소창이 한글로 보여 주는 것은 사용자 편의를 위한 표시일 뿐이고, 실제 전송되는 값은 인코딩된 형태입니다. 주소를 복사해 다른 곳에 붙여넣으면 %ED%95%9C...가 나오는 이유입니다.

인코딩을 두 번 하면

가장 자주 겪는 버그입니다.

  • 원본: 한글
  • 한 번 인코딩: %ED%95%9C%EA%B8%80
  • 두 번 인코딩: %25ED%2595%259C...

%가 다시 %25로 인코딩되면서 값이 망가집니다. 서버는 이를 디코딩해도 %ED%95%9C이라는 문자열을 얻을 뿐 한글로 돌아가지 않습니다.

이미 인코딩된 값을 다시 인코딩하지 않도록, 어느 단계에서 인코딩하는지 명확히 정해 두어야 합니다. 대개 URL을 조립하는 마지막 지점에서 한 번만 합니다.

이중 인코딩이 맞는 경우도 있습니다

위에서 이중 인코딩을 버그라고 했지만, URL 안에 URL을 값으로 넣을 때는 두 번 인코딩된 것처럼 보이는 결과가 정상입니다. 로그인 후 돌아갈 주소를 redirect_uri 파라미터에 넣는 경우가 대표적입니다.

  • 돌아갈 주소: https://so-yi.com/calc?year=2026
  • 이것을 값으로 넣으면: redirect_uri=https%3A%2F%2Fso-yi.com%2Fcalc%3Fyear%3D2026

안쪽 주소의 ?와 =가 인코딩되어야 바깥 URL의 파라미터 구분과 섞이지 않습니다. 안쪽 주소에 이미 %20 같은 인코딩이 있었다면 그 %도 %25가 되는 것이 맞습니다. 서버가 한 번 디코딩하면 원래 주소가 그대로 나옵니다. 문제가 되는 이중 인코딩은 같은 값을 같은 단계에서 두 번 인코딩하는 것이고, 값 안에 값을 넣는 중첩은 단계마다 한 번씩이라 정상입니다.

한글 도메인은 다른 방식을 씁니다

한글.kr 같은 한글 도메인은 퍼센트 인코딩이 아니라 퓨니코드로 바뀝니다. xn--으로 시작하는 알파벳 문자열이 그것입니다. 도메인 이름 체계가 ASCII만 받기 때문에 만들어진 별도 규칙이고, 브라우저가 알아서 변환합니다. 이 도구의 URL 전체 방식으로 한글 도메인을 인코딩하면 호스트 부분이 퍼센트로 인코딩되어 실제 브라우저가 쓰는 형태와 달라지므로, 도메인의 한글은 인코딩하지 말고 경로와 쿼리의 한글만 인코딩해야 합니다.

메신저로 보낸 링크가 깨질 때

카카오톡이나 문자로 한글이 든 주소를 보내면 링크가 한글 앞에서 끊기는 일이 있습니다. 메신저가 어디까지가 주소인지 판단할 때 한글이나 공백을 주소의 끝으로 보기 때문입니다. 보내기 전에 값 하나 방식으로 한글 부분만 인코딩하거나 URL 전체 방식으로 주소를 통째로 인코딩하면 전부 ASCII가 되어 끝까지 링크로 인식됩니다. 받는 사람의 브라우저는 인코딩된 주소를 그대로 열 수 있고, 주소창에는 다시 한글로 표시됩니다. 엑셀이나 문서에 하이퍼링크로 넣을 때도 같은 이유로 인코딩된 주소가 안전합니다.

인코딩되지 않는 문자

다음 문자들은 URL에서 안전하다고 규정되어 인코딩되지 않습니다.

A-Z a-z 0-9 - _ . ~

encodeURIComponent는 여기에 더해 !, ', (, ), *도 남겨 둡니다. 이 문자들이 문제가 되는 시스템이 있다면 직접 치환해야 합니다.

쿼리스트링을 직접 조립하지 마세요

문자열을 이어 붙여 URL을 만들면 인코딩을 빠뜨리기 쉽습니다. 대신 표준 API를 쓰세요.

const url = new URL("https://so-yi.com/search");
url.searchParams.set("q", "연봉 실수령액 & 세금");
// 알아서 인코딩됩니다

URLSearchParams는 값에 어떤 문자가 들어 있든 안전하게 처리합니다. 위 도구의 "URL 구성 요소" 표도 같은 API로 파싱한 결과입니다.

함께 확인하면 좋은 것

바이너리를 텍스트로 옮겨야 한다면 Base64 인코더를, 패턴으로 URL을 검사하려면 정규식 테스터를 이용하세요.

자주 묻는 질문

최종 수정 2026년 9월 6일