URL 인코딩이란 — 한글과 특수문자가 %EC처럼 바뀌는 이유 - Tooly 가이드

2026. 03. 19

URL 인코딩이란 — 한글과 특수문자가 %EC처럼 바뀌는 이유

URL에서 한글이 %EC%95%88처럼 변환되는 원리와 퍼센트 인코딩 방식. encodeURI vs encodeURIComponent 차이와 언어별 구현 코드까지.


URL 인코더/디코더 →

URL에서 한글이 깨지는 이유

네이버에서 "서울 날씨"를 검색하면 주소창에 %EC%84%9C%EC%9A%B8+%EB%82%A0%EC%94%A8 같은 URL이 나타난다. URL은 ASCII 문자 범위 안에서만 안전하게 전달되도록 설계됐기 때문에, 한글처럼 ASCII에 포함되지 않는 문자는 변환해야 한다.

퍼센트 인코딩의 원리

퍼센트 인코딩은 문자를 UTF-8 바이트로 변환하고, 각 바이트 앞에 %를 붙여 16진수로 표현하는 방식이다.

"안"이라는 글자는 UTF-8에서 3바이트로 표현된다: 0xEC 0x95 0x88 → %EC%95%88

공백 문자는 %20이다. URL에서 +로 표현하기도 하는데, +는 폼 데이터에서 공백을 나타내는 방식이고 순수 URL에서는 %20이 올바른 표현이다.

예약 문자와 비예약 문자

예약 문자: URL 구조에서 특별한 의미를 가진다. 데이터로 사용할 때는 반드시 인코딩해야 한다.

: / ? # [ ] @ ! $ & ' ( ) * + , ; =

비예약 문자: 인코딩하지 않아도 안전한 문자들이다.

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

JavaScript에서의 인코딩 함수

encodeURI(url): URL 전체를 인코딩할 때 쓴다. URL 구조에 필요한 문자는 인코딩하지 않는다.

encodeURIComponent(value): URL의 파라미터 값처럼 URL의 일부를 인코딩할 때 쓴다. 예약 문자를 포함해 모든 특수문자를 인코딩한다.

파라미터 값에 encodeURI 대신 encodeURIComponent를 써야 하는 이유: &=는 encodeURI에서 인코딩되지 않는데, 파라미터 값 안에 이 문자가 있으면 서버가 파라미터를 잘못 파싱한다.

언어별 URL 인코딩 함수

Python

from urllib.parse import quote, urlencode
quote("서울 날씨")  # '%EC%84%9C%EC%9A%B8%20%EB%82%A0%EC%94%A8'
urlencode({"q": "서울 날씨", "lang": "ko"})

PHP

urlencode("서울 날씨");       // 폼 데이터 방식
rawurlencode("서울 날씨");    // RFC 3986 방식

실제로 발생하는 버그 사례

카카오 API나 네이버 API에 한글 검색어를 파라미터로 넘길 때 인코딩을 빠뜨리면 400 Bad Request나 빈 결과가 반환된다. URLSearchParams나 axios의 params 옵션을 쓰면 자동으로 처리된다.

// 직접 연결 — 인코딩 누락 위험
fetch(`/api/search?q=서울 날씨`);

// URLSearchParams 사용 — 자동 인코딩
const params = new URLSearchParams({ q: "서울 날씨" });
fetch(`/api/search?${params}`);
목록