유틸리티

URL 인코딩이란? 한글 URL 깨짐 원인과 해결법

API에 한글 검색어를 파라미터로 넘겼더니 서버에서 이상한 문자열로 받는다. 브라우저 주소창에 한글을 넣으면 잘 보이는데, 복사해서 다른 곳에 붙여넣으면 "%EC%84%9C%EC%9A%B8"처럼 변한다. 이게 URL 인코딩이다.

왜 URL에 한글을 그대로 쓰면 안 되나

URL은 원래 ASCII 문자(영문, 숫자, 일부 특수문자)만 허용하도록 설계됐다. 한글, 공백, 특수문자(&, =, ? 등)는 URL에서 특별한 의미를 갖거나 규격에 맞지 않아서, 그대로 넣으면 서버가 제대로 해석하지 못한다.

그래서 이런 문자를 퍼센트 인코딩(%XX)으로 변환한다. 각 바이트를 16진수로 표기하고 앞에 %를 붙이는 방식이다.

변환 예시

원문인코딩 결과설명
서울%EC%84%9C%EC%9A%B8한글 1자 = 3바이트(UTF-8)
공백%20 또는 +공백 인코딩
&%26쿼리 구분자와 충돌 방지
=%3D키-값 구분자와 충돌 방지

encodeURI와 encodeURIComponent의 차이

JavaScript에서 URL을 인코딩할 때 두 함수 중 어떤 걸 쓸지 헷갈리는 경우가 많다.

encodeURI()
URL 전체를 인코딩한다. 단, URL 구조 문자(://?#[]@!$&'()*+,;=)는 변환하지 않는다. URL을 통째로 넘길 때 적합하다.
encodeURIComponent()
모든 특수문자를 인코딩한다. 쿼리 파라미터 값에 URL이나 특수문자가 포함될 때 사용한다.
// 파라미터 값에 URL이 포함된 경우
const url = "https://example.com?redirect=" + encodeURIComponent("https://other.com/path?q=서울")
// 결과: https://example.com?redirect=https%3A%2F%2Fother.com%2Fpath%3Fq%3D%EC%84%9C%EC%9A%B8
주의 파라미터 값을 encodeURI로 인코딩하면 &, = 같은 문자가 변환되지 않아서 서버가 파라미터 구분을 잘못할 수 있다. 파라미터 값에는 반드시 encodeURIComponent를 쓰는 게 맞다.

디코딩이 필요한 상황

반대로 인코딩된 URL을 사람이 읽을 수 있는 형태로 복원하는 게 디코딩이다. 로그 파일에서 URL을 분석할 때, 또는 API 응답에서 인코딩된 문자열을 원래 텍스트로 되돌릴 때 쓴다.

코드를 쓰지 않고 빠르게 인코딩/디코딩을 확인하려면 URL 인코딩 변환 도구가 편하다. 텍스트를 붙여넣으면 실시간으로 결과가 나오고, encodeURIComponent 옵션도 선택할 수 있다. 입력과 출력의 크기 차이도 표시해줘서 인코딩으로 URL이 얼마나 길어지는지 감을 잡을 수 있다.

URL 인코딩은 웹 개발에서 피할 수 없는 기본이다. 원리를 한 번 정리해두면 한글 깨짐, 파라미터 오류 같은 문제를 만났을 때 원인을 바로 파악할 수 있다.