URL 인코딩/디코딩이 필요한 순간과 쉽게 처리하는 법
URL 인코딩(퍼센트 인코딩)이 무엇이고 언제 필요한지, 한글·특수문자·UTM 값을 다룰 때 주의할 점과 무료 인코더/디코더로 쉽게 변환하는 법을 정리했습니다.
링크를 공유했더니 한글이 %ED%95%9C처럼 깨져 보인 적이 있을 것입니다. 반대로 파라미터에 한글을 넣었더니 링크가 아예 동작하지 않은 경우도 있습니다. 둘 다 URL 인코딩과 관련된 문제입니다.
URL 인코딩이란
URL 인코딩(퍼센트 인코딩)은 URL에서 그대로 쓸 수 없는 문자를 %XX 형식으로 바꾸는 규칙입니다. URL 표준인 RFC 3986이 URL에 안전하게 쓸 수 있는 문자(영문, 숫자, 일부 기호)를 정해 두었고, 그 밖의 문자는 인코딩해야 브라우저와 서버가 올바르게 해석합니다.
자주 마주치는 문자의 변환 결과는 다음과 같습니다.
| 문자 | 인코딩 결과 | 자주 나오는 상황 |
|---|---|---|
| 공백 | %20 | 캠페인명, 검색어 |
한글 한 | %ED%95%9C | 한글 슬러그, 검색어, 태그 |
& | %26 | 값 안에 &가 들어갈 때 (파라미터 구분자와 충돌) |
? | %3F | 값 안에 URL이 통째로 들어갈 때 |
= | %3D | 값 안에 URL이 통째로 들어갈 때 |
# | %23 | 값에 해시태그 텍스트를 넣을 때 |
% | %25 | 이중 인코딩의 원인 |
인코딩이 필요한 순간
특히 다음 상황에서 인코딩이 필요합니다.
- 파라미터 값에 한글이나 특수문자가 들어갈 때: 검색어, 이름, 태그 등.
- UTM 값에 공백이나 기호가 있을 때:
utm_campaign=여름 세일은여름%20세일로 인코딩해야 안전합니다. UTM 파라미터를 다룰 때 자주 마주칩니다. - URL을 다른 URL의 파라미터로 넘길 때:
?redirect=뒤에 붙는 주소는 통째로 인코딩해야 중간에 잘리지 않습니다. - 스프레드시트나 메신저에서 링크가 중간에 끊길 때: 인코딩되지 않은 한글·공백이 있으면 링크 인식이 그 지점에서 멈추는 경우가 많습니다. 인코딩하거나 단축 링크로 바꾸면 해결됩니다.
인코더 디코더 사용법
직접 규칙을 외울 필요는 없습니다. 무료 URL 인코더/디코더에 값을 넣으면 즉시 변환됩니다.
- encodeURIComponent: 파라미터 값 하나를 인코딩할 때.
://?#같은 구조 문자까지 모두 바꿉니다. - encodeURI: 전체 URL을 인코딩할 때. URL 구조 문자는 그대로 둡니다.
받은 인코딩된 URL이 무엇인지 확인하려면 디코딩해 읽기 쉬운 형태로 되돌리거나, URL 파서로 구성 요소를 분해해 볼 수 있습니다.
코드에서 처리한다면 JavaScript 내장 함수 한 줄로 충분합니다.
encodeURIComponent('여름 세일') // '%EC%97%AC%EB%A6%84%20%EC%84%B8%EC%9D%BC'
decodeURIComponent('%EC%97%AC%EB%A6%84%20%EC%84%B8%EC%9D%BC') // '여름 세일'
이중 인코딩이라는 함정
실무에서 가장 자주 만나는 문제는 이중 인코딩입니다. 이미 인코딩된 문자열을 한 번 더 인코딩하면, %ED%95%9C의 %가 %25로 바뀌어 %25ED%2595%259C처럼 됩니다. 이 링크는 디코딩을 한 번 해도 여전히 깨져 보입니다.
이중 인코딩은 보통 이런 흐름에서 생깁니다.
- 도구나 스프레드시트에서 이미 인코딩된 URL을 복사합니다.
- 그 URL을 다시 인코딩 처리가 있는 다른 도구(폼, 스크립트)에 붙여 넣습니다.
- 두 번 인코딩된 링크가 배포됩니다.
의심될 때는 디코더에 두 번 넣어 보세요. 두 번째 디코딩에서 정상 한글이 나오면 이중 인코딩이 맞습니다. 예방법은 하나입니다. 인코딩은 배포 직전에 한 번만 합니다.
상황별 처리법 정리
- UTM 값에 한글·공백이 있을 때:
utm_campaign=여름 세일처럼 값만 인코딩합니다. UTM 빌더를 쓰면 값 인코딩이 자동 처리됩니다. - URL을 다른 URL의 파라미터로 넘길 때:
?redirect=https://...의 값은encodeURIComponent로 통째로 인코딩해야&뒤가 잘리지 않습니다. - 메신저에 공유할 때: 인코딩된 한글 URL은 길이가 3배 이상 늘어나 잘리거나 지저분해집니다. 이런 링크일수록 단축이 효과적입니다.
한글 도메인은 다르게 처리됩니다
한글.kr 같은 한글 도메인은 퍼센트 인코딩이 아니라 퓨니코드(Punycode) 라는 별도 규칙으로 변환됩니다. 브라우저 주소창에는 한글로 보여도, 실제로는 xn--으로 시작하는 형태로 전송됩니다. 즉 같은 URL 안에서도 도메인은 퓨니코드, 경로와 파라미터의 한글은 퍼센트 인코딩으로 서로 다르게 처리됩니다.
복사한 링크에서 xn--이 보인다면 깨진 것이 아니라 한글 도메인이 변환된 것이니 놀라지 않아도 됩니다. 어떤 도메인인지 확인하고 싶다면 URL 파서에 넣어 구성 요소를 분해해 보면 됩니다. 반대로 낯선 링크의 xn-- 도메인이 유명 사이트를 흉내 내는 경우도 있으므로, 출처가 불분명한 링크는 도메인을 풀어 확인하는 습관이 안전합니다.
애초에 인코딩이 필요 없는 링크 만들기
공유할 링크라면 처음부터 인코딩이 필요 없는 형태로 만드는 것이 가장 깔끔합니다. 한글 경로 대신 영문 슬러그를 쓰는 방식입니다. "여름 세일" 페이지라면 summer-sale처럼 소문자와 하이픈으로 짓고, 한국어 문구는 무료 슬러그 생성기로 URL 친화적인 형태로 변환할 수 있습니다. 사람이 읽을 수 있는 링크는 지저분한 인코딩 문자열보다 신뢰를 얻고 클릭도 잘 됩니다.
인코딩된 긴 URL은 단축이 답
인코딩을 거치면 URL이 훨씬 길어집니다. 이런 링크를 그대로 공유하면 지저분하고, 메신저에서 잘리기도 합니다. 단축 링크로 줄이면 깔끔해질 뿐 아니라 클릭 추적까지 됩니다. Edgelink는 인코딩된 복잡한 URL도 짧고 추적 가능한 링크로 바꿔 줍니다.
자주 묻는 질문
encodeURIComponent와 encodeURI의 차이는 무엇인가요?
encodeURIComponent는 파라미터 값 하나를 모든 특수문자까지 인코딩하고, encodeURI는 전체 URL에서 구조 문자(://?# 등)는 그대로 둡니다. 값에는 Component를, 전체 URL에는 URI를 씁니다.
링크에 한글이 %ED%95%9C처럼 깨져 보여요.
URL 인코딩된 상태입니다. 무료 URL 디코더에 넣으면 원래 한글로 되돌려 읽을 수 있습니다.
공백은 +와 %20 중 무엇으로 인코딩해야 하나요?
헷갈리면 %20을 쓰세요. +는 HTML 폼 전송 방식에서 유래한 표기라 쿼리 문자열에서만 공백으로 해석되고, 경로에서는 문자 그대로 +로 처리됩니다. %20은 어디서나 공백으로 해석되어 안전합니다.
디코딩했는데도 %25ED 같은 값이 나와요.
이중 인코딩된 URL입니다. 이미 인코딩된 문자열을 한 번 더 인코딩하면 %가 %25로 바뀝니다. 디코더에 한 번 더 넣어 두 번 디코딩하면 원래 값이 나옵니다.

