퍼센트 인코딩이 필요한 이유
URL은 ASCII 문자 일부만 그대로 쓸 수 있습니다. 한글, 공백, 그리고 ? & = #처럼 URL 구조에서 역할이 있는 기호는 값 안에 들어갈 때 바이트 단위로 %XX 형태로 바꿔야 합니다. 한글 한 글자는 UTF-8로 3바이트이므로 가는 %EA%B0%80이 됩니다. 브라우저 주소창이 한글을 그대로 보여 주는 것은 표시만 그렇게 할 뿐, 실제 요청은 인코딩된 형태로 나갑니다. 이 페이지의 변환은 브라우저 안에서 끝나고 서버로 전송되지 않습니다.
encodeURIComponent vs encodeURI
encodeURIComponent는 값 하나를 통째로 안전하게 만듭니다. / ? = &도 모두 바꾸므로 검색어처럼 파라미터 값에 넣을 문자열에 씁니다. encodeURI는 URL 전체를 대상으로 하여 구조 기호는 남기고 한글·공백만 바꿉니다. 완성된 주소를 정리할 때는 후자, ?q= 뒤에 붙일 값은 전자입니다. 값에 &가 들어 있는데 encodeURI를 쓰면 파라미터가 쪼개지는 사고가 납니다.
공백은 %20인가 +인가
둘 다 맞지만 맥락이 다릅니다. URL 규격(RFC 3986)에서는 공백이 %20입니다. HTML 폼을 GET/POST로 보낼 때의 application/x-www-form-urlencoded 형식에서는 공백을 +로 적습니다. 그래서 검색 엔진 주소창에서는 +가 보이고, API 호출에서는 %20이 보입니다. 서버 프레임워크는 대부분 쿼리 문자열에서 둘 다 공백으로 풀지만, 경로(path) 부분의 +는 그냥 더하기 기호로 남습니다. 옵션을 켜면 이 형식으로 바꿉니다.
이중 인코딩 주의
이미 인코딩된 문자열을 다시 인코딩하면 % 자체가 %25로 바뀌어 %25EA%25B0 같은 결과가 됩니다. 서버에서 디코딩해도 원문이 나오지 않습니다. 결과에 %25가 많이 보이면 이중 인코딩을 의심해야 합니다.
자주 묻는 질문
디코딩이 오류가 나요.
% 뒤에 16진수 두 자리가 아닌 글자가 있거나(예: "100%"), 멀티바이트 문자 중간에서 잘린 경우입니다. 이런 문자열은 원래부터 올바른 인코딩이 아닙니다.
한글이 %u로 시작하는 형태로 되어 있어요.
오래된 escape() 함수의 출력입니다. 표준이 아니므로 이 도구로는 디코딩되지 않습니다. 가능하면 생성 측에서 encodeURIComponent로 바꾸는 것이 좋습니다.