URL 인코더 / 디코더

URL 퍼센트 인코딩/디코딩.

Loading…

모든 처리는 브라우저 내부에서 실행됩니다 — 파일·입력은 서버로 전송되지 않습니다.

사용법

오른쪽 위에서 Encode·Decode를 전환하고 텍스트를 붙여 넣으면 오른쪽 패널에 결과가 실시간으로 표시됩니다. Encode는 표준 `encodeURIComponent`를 실행합니다. 비예약 문자 집합(A–Z·a–z·0–9·`-_.~`) 밖의 바이트는 모두 `%XX` 형식의 UTF-8 16진 표기로 치환됩니다. Decode는 그 역으로, 잘못된 `%` 이스케이프가 포함되면 명확한 에러를 표시합니다.

URL에 값을 실어 보낼 때 사용합니다. 쿼리 문자열 파라미터, 경로 세그먼트, 리다이렉트 대상 같은 경우입니다. 폼이나 현대 HTTP 라이브러리는 보통 인코딩을 자동 처리하지만, URL을 직접 조립하거나 웹훅 콜백을 디버깅하거나 동료가 보낸 트래킹 링크를 붙여 넣을 때 이 도구가 유용합니다. 모든 처리는 브라우저 안에서 끝나므로 토큰이나 개인정보가 담긴 URL도 기기 밖으로 나가지 않습니다.

예제

공백과 비ASCII문자가 들어간 텍스트 인코드

입력
hello world & 안녕하세요
출력
hello%20world%20%26%20%EC%95%88%EB%85%95%ED%95%98%EC%84%B8%EC%9A%94

공백은 %20이 됩니다. 한국어 텍스트는 먼저 UTF-8로 인코드되므로 한글 음절 한 글자가 3바이트(%XX%XX%XX)로 펼쳐집니다. 앰퍼샌드도 이스케이프되는 이유는 encodeURIComponent가 값 레벨 문자로 다루기 때문입니다. 그대로 쿼리 문자열에 넣어도 안전합니다.

퍼센트 인코드된 경로 디코드

입력
%2Fposts%2F%ED%95%9C%EA%B8%80-%EC%A0%9C%EB%AA%A9%2F
출력
/posts/한글-제목/

슬래시가 인코드된 이유는 encodeURIComponent가 값 레벨 문자로 다루기 때문입니다. 디코드하면 원래 UTF-8문자열이 복원됩니다. 요청 로그에 %2F가 보인다면 생성 측이 URI레벨이 아닌 컴포넌트 레벨 인코더를 쓴 신호입니다.

잘못된 이스케이프 감지

입력
hello %2 world
출력
URI malformed

decodeURIComponent는 `%` 뒤에 16진수 2자리가 따라오지 않으면 예외를 던집니다. 흔한 원인은 붙여 넣기 원본에서 일부 문자가 이미 디코드되어 `%`만 외로이 남아 있는 경우입니다.

자주 묻는 질문

URL 인코딩은 암호화와 같은가요?

아니요. 퍼센트 인코딩은 키 없이 누구나 복원할 수 있는 가역 변환입니다. 임의의 텍스트를 URL구문(`?`·`&`·`=`·공백·`#`가 이미 구조적 의미를 갖는다) 안에 담기 위한 장치이며 내용을 숨기는 용도가 아닙니다. 보안 계층으로 사용해서는 안 됩니다.

encodeURI와 encodeURIComponent — 이 도구는 어느 쪽을 쓰나요?

encodeURIComponent입니다. 이 차이는 중요합니다. encodeURI는 `:` `/` `?` `&` `#` 같은 URL구조 문자를 보존하며 URL전체를 다루는 데 적합합니다. 반면 encodeURIComponent는 그것들까지 이스케이프하며 URL에 끼워 넣을 개별 값을 다루는 데 적합합니다. URL 전체를 붙여 넣고 쿼리 값만 변환하고 싶다면 먼저 손으로 분리하세요.

디코드할 때 `+`가 공백으로 바뀌지 않는 이유는?

encodeURIComponent는 공백을 `%20`으로 인코드하며 `+`는 생성하지 않습니다. `+` = 공백 관례는 HTML폼 전송이 사용하는 옛 `application/x-www-form-urlencoded` 형식의 것입니다. 입력이 `+`를 공백으로 사용한다면, 이 도구로 디코드하기 전에 `+`를 `%20`으로 치환하거나, 폼 urlencoded용 디코더를 사용하세요.

브라우저 URL바에는 `한국`으로 보이는데 붙여 넣으면 `%ED%95%9C%EA%B5%AD`이 되는 이유는?

현대 브라우저는 가독성을 위해 퍼센트 인코드된 UTF-8을 원래 문자로 렌더링하지만, 정확한 전송을 위해 내부에는 인코드된 원본 형태를 저장하고 그것을 복사합니다. 두 표현은 같은 URL의 동등한 형태이며, 이 도구에서는 둘 다 동일한 문자열로 디코드됩니다.

국제화 도메인 이름(IDN)도 지원하나요?

지원하지 않습니다. 이 도구는 값 측(경로·쿼리·프래그먼트)만 다룹니다. 비ASCII문자가 포함된 호스트명은 퍼센트 인코딩이 아닌 Punycode(`xn--…`)를 사용하며 별도의 변환이 필요합니다. 현대 브라우저는 Unicode 형식으로 표시하지만 내부에서는 Punycode로 전송합니다.

인코더가 `-`·`_`·`.`·`~`를 그대로 두는 이유는?

이 4글자는 RFC 3986에서 *비예약* 문자 집합으로 정의되어 있습니다. URL구조 문자와 혼동될 여지가 없어 이스케이프가 필요 없습니다. encodeURIComponent는 의도적으로 그대로 통과시킵니다.

관련 개념

퍼센트 인코딩(URL인코딩이라고도 부름)은 RFC 3986에 정의되어 있습니다. 비예약 문자 집합(A–Z·a–z·0–9·`-` `_` `.` `~`) 외 모든 바이트는 `%` 뒤에 대문자 16진수 2자리가 붙는 형태가 됩니다. URL은 바이트 지향이므로 비ASCII텍스트는 먼저 UTF-8로 변환된 뒤 각 바이트가 퍼센트 이스케이프됩니다. 3바이트짜리 한글 음절이 9글자(`%XX%XX%XX`)로 펼쳐지는 이유가 그것입니다.

JavaScript에는 관련 함수가 4개 있으며 동작이 다릅니다. `encodeURI`와 `decodeURI`는 URL구조 문자(`: / ? & = # @`)를 그대로 두며 URL전체를 다루는 데 적합합니다. `encodeURIComponent`와 `decodeURIComponent`는 구조 문자도 이스케이프하며 URL에 끼워 넣을 개별 값을 다루는 데 적합합니다. 이 도구는 후자 쌍을 사용합니다. 별개의 형식인 `application/x-www-form-urlencoded`는 공백을 `%20`이 아닌 `+`로 인코드하며 HTML폼이 생성합니다. 많은 백엔드 프레임워크가 두 형식을 모두 받습니다.

퍼센트 인코딩과 혼동하기 쉬운 인접 개념이 3개 있습니다. **Base64**는 바이너리를 ASCII텍스트에 담지만 `+`와 `/`를 포함해 자체적으로 URL이스케이프가 필요합니다(base64url이 이 문제를 해결합니다). **HTML 엔티티**(`&`·`😀`)는 HTML용 이스케이프이며 URL용이 아닙니다. **Punycode**(`xn--…`)는 호스트명이 퍼센트 인코딩을 사용할 수 없기 때문에 국제화 도메인 이름을 처리합니다.

관련 글

관련 도구