URL 특수문자 처리 방법 완벽 정리 - 퍼센트 인코딩 원리와 언어별 코드 예제
한글, 공백, 특수기호가 포함된 URL을 안전하게 다루는 방법을 정리합니다. 인코딩 원리와 자바스크립트, 파이썬 코드 예제까지 한 번에 확인하세요.
![]()
URL을 다루다 보면 한글이 깨지거나 검색 파라미터가 잘못 전달되는 경험을 한 번쯤 해보셨을 겁니다. 주소창에 멀쩡히 붙여넣었는데 서버에서는 다른 값으로 인식하거나, 링크를 공유했더니 일부 글자가 사라지는 문제도 자주 발생합니다. 이런 현상의 대부분은 URL 특수문자 처리 방법이 제대로 적용되지 않아서 생깁니다.
URL에서 특수문자가 문제가 되는 이유
URL은 원래 ASCII 문자 중에서도 일부만 안전하게 쓸 수 있도록 설계되었습니다. 표준 문서인 RFC 3986에서는 알파벳, 숫자, 그리고 -, _, ., ~ 네 가지 문자를 비예약(unreserved) 문자로 정의하고, 나머지는 특별한 의미를 가지거나 별도 처리가 필요한 문자로 분류합니다.
예를 들어 ?는 쿼리 스트링의 시작을 알리는 구분자이고, &는 파라미터를 나누는 역할을 합니다. 그런데 검색어 자체에 이런 기호가 포함되어 있다면 서버는 데이터가 아닌 구분자로 해석해 버립니다. 한글이나 일본어처럼 ASCII 범위를 벗어나는 문자도 마찬가지로 그대로 전달하면 깨지거나 거부될 수 있습니다.
URL은 글로벌 표준이지만, 그 안에서 안전하게 쓸 수 있는 문자는 의외로 좁습니다. 그래서 인코딩이라는 약속이 필요합니다.
퍼센트 인코딩의 원리
URL 특수문자 처리 방법의 핵심은 퍼센트 인코딩(percent-encoding)입니다. 안전하지 않은 문자를 %XX 형태로 바꾸는 방식인데, 여기서 XX는 해당 문자의 바이트 값을 16진수로 표기한 것입니다.
예를 들어 공백 문자는 ASCII 코드 0x20이므로 %20으로 변환됩니다. 한글의 경우 UTF-8로 먼저 인코딩한 뒤 각 바이트를 퍼센트 인코딩하므로 한 글자가 보통 9자리(%XX%XX%XX) 형태로 표현됩니다. 글자 하나가 길게 늘어나는 셈이지만, 어떤 시스템을 거쳐도 안전하게 전달됩니다.
주요 특수문자별 인코딩 값
실무에서 자주 마주치는 문자들의 변환 결과를 정리했습니다. 표를 보면서 머릿속에 자주 쓰이는 값 몇 개만이라도 익혀두면 디버깅이 훨씬 빨라집니다.
| 문자 | 인코딩 결과 | 주의 사항 |
|---|---|---|
| 공백 | %20 | 폼 전송 시 +로 표기되기도 함 |
| ? | %3F | 쿼리 스트링 시작 구분자 |
| & | %26 | 파라미터 구분자 |
| = | %3D | 키-값 구분자 |
| # | %23 | 프래그먼트 식별자 |
| / | %2F | 경로 구분자, 파라미터 값 안에서만 인코딩 |
| 한글 '가' | %EA%B0%80 | UTF-8 3바이트 |
프로그래밍 언어별 구현 방법
자바스크립트
브라우저와 Node.js 모두 encodeURIComponent와 encodeURI 두 함수를 제공합니다. 둘은 비슷해 보이지만 동작 범위가 다르므로 용도를 구분해서 써야 합니다.
- encodeURI: 전체 URL을 인코딩하되 :/?#[]@!$&'()*+,;=는 그대로 둠
- encodeURIComponent: 위 문자들까지 모두 인코딩 (파라미터 값에 사용)
- decodeURIComponent: 디코딩이 필요할 때 사용
쿼리 파라미터의 값을 만들 때는 encodeURIComponent를 쓰는 것이 안전합니다. URLSearchParams 객체를 사용하면 자동으로 처리되므로 직접 인코딩 함수를 호출할 일이 줄어듭니다.
파이썬
표준 라이브러리 urllib.parse의 quote와 quote_plus를 사용합니다. quote는 슬래시를 기본으로 보존하고, quote_plus는 공백을 +로 바꿉니다. requests 라이브러리는 params 인자를 넘기면 내부에서 알아서 인코딩해 주므로 일반적인 API 호출에서는 직접 처리할 일이 거의 없습니다.
자주 발생하는 실수와 해결법
현장에서 반복적으로 보게 되는 실수 몇 가지를 정리합니다. 한 번이라도 비슷한 증상을 겪었다면 아래 항목부터 점검해 보세요.
- 이중 인코딩: 이미 인코딩된 문자열을 다시 인코딩하면 %가 %25로 바뀌어 디코딩이 두 번 필요해집니다.
- 경로와 쿼리를 한꺼번에 인코딩: 슬래시까지 인코딩되어 라우팅이 깨질 수 있습니다.
- EUC-KR과 UTF-8 혼용: 옛 시스템과 연동할 때 인코딩 기준을 통일하지 않으면 한글이 깨집니다.
- 공백을 + 또는 %20 중 한쪽만 가정: 디코딩 단계에서는 양쪽 형식을 모두 처리해야 안전합니다.
특히 공유 링크를 생성하는 기능을 만들 때 이런 문제가 자주 보입니다. 사용자가 입력한 검색어에 #이나 &가 들어가면 그대로 URL에 붙이는 코드가 의외로 많습니다. 사용자 입력을 받는 부분이 있다면 인코딩 처리를 빼먹지 않아야 합니다.
실무에서 함께 쓰면 좋은 도구
인코딩 결과를 빠르게 확인하고 싶을 때는 브라우저 개발자 도구의 콘솔에서 encodeURIComponent('테스트')를 실행하는 것이 가장 빠릅니다. 별도의 사이트를 켜지 않아도 되고, 결과를 즉시 복사해서 쓸 수 있습니다. 디코딩이 필요하면 decodeURIComponent로 거꾸로 풀어보면 됩니다.
웹 작업을 하다 보면 URL 처리 외에도 다양한 변환 도구가 필요해집니다. 디자인 작업에서 색상 코드를 RGB, HEX, HSL 사이에서 변환할 때는 색상 변환기 같은 도구가 유용하고, 오프라인 매장 운영자라면 바코드 생성기처럼 즉시 결과를 받을 수 있는 웹 유틸리티를 북마크해 두면 작업 시간을 크게 줄일 수 있습니다.
URL 특수문자 처리는 한 번 익혀두면 평생 쓰는 기본기입니다. 오늘 정리한 인코딩 원리와 함수 두세 개만 정확히 기억해도 대부분의 깨짐 문제는 막을 수 있습니다. 지금 작업 중인 코드에서 사용자 입력을 URL에 직접 붙이는 부분이 있다면 encodeURIComponent로 감싸는 한 줄을 추가하는 것부터 시작해 보세요.