홈
DT

URL 인코딩 · 디코딩 & 쿼리 파서

퍼센트 인코딩을 양방향으로 바꾸고 쿼리 파라미터를 표로 편집합니다.

이 도구는 100% 브라우저에서 실행됩니다. 입력한 데이터는 서버로 전송되지 않습니다.

URL에는 쓸 수 있는 문자가 정해져 있습니다. 한글, 공백, &, ?, # 같은 문자를 주소에 그대로 넣으면 구조가 깨지거나 값의 일부가 잘려 나갑니다. 퍼센트 인코딩은 이런 문자를 %XX 형태의 안전한 표기로 바꾸는 규칙이고, 이 도구는 그 변환을 양방향으로 처리합니다.

세 가지 인코딩 방식을 구분해 제공하는 점이 중요합니다. 같은 문자열이라도 쿼리 값 하나를 넣을 때, URL 전체를 다룰 때, HTML 폼으로 전송할 때 인코딩해야 하는 범위가 다릅니다. 이 차이를 모르고 아무 함수나 쓰면 파라미터가 통째로 사라지거나 값 안의 & 가 구분자로 잘못 해석되는 버그가 생깁니다.

사용 방법

  1. 방향과 방식 고르기 — 인코딩과 디코딩 중 방향을 정하고, 아래에서 세 가지 방식 중 하나를 고릅니다. 방식을 바꾸면 설명 문구가 함께 바뀌므로 어떤 상황에 맞는 것인지 확인하고 고르세요.
  2. 결과 확인하고 크기 비교하기 — 오른쪽에 변환 결과가 즉시 나타나고, 아래에 바이트 수와 원본 대비 증감이 표시됩니다. 한글은 UTF-8에서 글자당 3바이트이고 퍼센트 인코딩하면 %XX 세 쌍, 즉 9바이트가 되므로 길이가 세 배로 늘어납니다. URL 길이 제한에 걸리는지 판단할 때 유용합니다.
  3. URL 구조 뜯어보기 — 전체 주소를 넣으면 프로토콜·호스트·포트·경로·쿼리·해시로 분해한 표가 나타납니다. 어디까지가 경로이고 어디부터가 쿼리인지 헷갈릴 때, 또는 포트가 제대로 붙었는지 확인할 때 씁니다.
  4. 쿼리 파라미터 직접 고치기 — 쿼리가 있는 주소를 넣으면 파라미터가 키·값 표로 펼쳐집니다. 값을 고치거나 행을 추가·삭제하면 아래에 새 URL이 만들어지고, URL 복사로 바로 가져갈 수 있습니다. 긴 추적 파라미터가 붙은 주소를 정리할 때 편합니다.

자주 묻는 질문

encodeURI와 encodeURIComponent의 차이가 무엇인가요?

인코딩하는 문자의 범위가 다릅니다. encodeURIComponent(컴포넌트)는 /, ?, &, =, # 까지 전부 바꾸고, encodeURI(전체 URL)는 이 문자들을 URL 구조의 일부로 보고 그대로 둡니다.

실무 규칙은 간단합니다. 값 하나를 넣을 때는 컴포넌트, 완성된 주소를 다룰 때는 전체 URL입니다. 예를 들어 검색어를 쿼리에 넣는다면 ?q=${encodeURIComponent(검색어)} 처럼 값에만 적용해야 합니다. 여기에 encodeURI를 쓰면 검색어에 포함된 & 가 파라미터 구분자로 해석되어 값이 잘립니다.

공백이 어떨 때는 %20이고 어떨 때는 +인가요?

+는 application/x-www-form-urlencoded 형식에서만 공백을 뜻합니다. HTML 폼을 GET으로 전송할 때 브라우저가 만드는 형식이 이것이라 쿼리 문자열에서 자주 보입니다.

URL 경로에서는 + 가 그냥 더하기 기호입니다. 그래서 경로에 있는 + 를 공백으로 잘못 디코딩하면 값이 달라집니다. 이 도구의 폼 (+) 방식은 + 를 공백으로 처리하고 나머지 두 방식은 그대로 두므로, 디코딩 결과가 이상하면 방식을 바꿔 보세요.

이미 인코딩된 URL을 또 인코딩했습니다.

이중 인코딩이 되어 % 가 %25 로 바뀝니다. %20 이 %2520 이 되는 식이라 디코딩을 두 번 해야 원래 값이 나옵니다.

한 번 디코딩했을 때 여전히 %XX 가 남아 있다면 이중 인코딩된 것이니 한 번 더 디코딩하세요. 이 문제는 보통 이미 인코딩된 값을 다시 인코딩 함수에 넣어서 생깁니다. 값이 인코딩된 상태인지 아닌지를 코드 흐름 안에서 명확히 정해 두는 것이 근본적인 해결책입니다.

URL에 길이 제한이 있나요?

표준에는 없지만 실제로는 여러 곳에서 제한이 걸립니다. 인터넷 익스플로러가 2,083자로 가장 짧았고, 요즘 브라우저는 대체로 수만 자를 허용합니다. 문제는 서버 쪽으로, nginx는 기본 8KB, 아파치는 8,190바이트, 그리고 여러 CDN과 프록시가 각자의 상한을 둡니다.

안전하게는 2,000자 안쪽으로 유지하는 것이 좋습니다. 한글이 많이 들어간 검색어를 쿼리에 넣으면 인코딩 후 길이가 세 배가 되므로 생각보다 빨리 늘어납니다. 데이터가 크다면 GET 쿼리 대신 POST 본문으로 보내세요.

알아두면 좋은 개념

예약 문자와 비예약 문자

RFC 3986은 URL에 쓰이는 문자를 두 갈래로 나눕니다. 비예약 문자(A-Z a-z 0-9 - . _ ~)는 어디에 있든 그대로 써도 되고 인코딩할 필요가 없습니다. 예약 문자(: / ? # [ ] @ ! $ & ' ( ) * + , ; =)는 URL의 구조를 나타내는 역할이 있어서, 구조가 아니라 데이터로 쓰려면 반드시 인코딩해야 합니다.

예를 들어 ? 는 쿼리의 시작을 뜻하므로, 검색어에 ? 가 들어 있다면 %3F 로 바꿔야 그 위치에서 쿼리가 시작된다고 오해받지 않습니다. 인코딩 함수들이 서로 다르게 동작하는 이유도 이 예약 문자 목록 중 어디까지를 건드리느냐의 차이입니다.

한글 URL은 어떻게 동작하는가

브라우저 주소창에 한글 주소를 입력하면 화면에는 한글로 보이지만 실제 요청에는 UTF-8로 인코딩된 퍼센트 표기가 실려 나갑니다. 주소창이 사용자에게 읽기 좋게 되돌려 보여 줄 뿐입니다.

도메인 이름은 규칙이 다릅니다. 퍼센트 인코딩 대신 퓨니코드(Punycode)라는 방식으로 한국.kr 이 xn--3e0b707e.kr 같은 ASCII 표기로 변환됩니다. 그래서 경로에 있는 한글과 도메인에 있는 한글은 완전히 다른 방식으로 처리되며, 도메인에는 퍼센트 인코딩을 쓸 수 없습니다.

해시(#)는 서버로 가지 않는다

URL의 # 뒤 부분(프래그먼트)은 브라우저 안에서만 쓰이고 HTTP 요청에 포함되지 않습니다. 원래는 문서 안 특정 위치로 이동하기 위한 것이고, 요즘은 SPA 라우팅이나 OAuth 암묵적 흐름에서 토큰을 전달하는 데 쓰입니다.

이 성질 때문에 서버 로그에는 프래그먼트가 남지 않습니다. 분석 도구에서 # 뒤 값이 집계되지 않는 이유이고, 반대로 민감한 값을 잠깐 전달할 때 서버 로그에 남기지 않으려고 일부러 프래그먼트를 쓰기도 합니다. 다만 브라우저 히스토리와 리퍼러에는 남을 수 있으니 안전한 저장소로 착각하면 안 됩니다.

함께 쓰면 좋은 도구

최종 업데이트: 2026-08-13