네이버 블로그 글 주소를 카카오톡에 보냈더니 한글 부분이 %ED%95%9C%EA%B8%80 같은 문자열로 바뀌어 있다. 받는 쪽에서는 링크가 중간에 끊겨서 클릭해도 404 에러가 뜬다. 이게 URL 인코딩 문제다.
URL에 한글이 들어가면 깨지는 이유
URL은 원래 영문 알파벳, 숫자, 일부 특수문자만 허용한다. RFC 3986 표준에서 정한 규칙이다. 한글, 일본어, 중국어 같은 비ASCII 문자는 URL에 직접 넣을 수 없기 때문에, 브라우저가 자동으로 퍼센트 인코딩(Percent Encoding)을 적용한다.
- 퍼센트 인코딩
- 문자를 UTF-8 바이트로 변환한 뒤, 각 바이트를
%XX형태로 표현하는 방식. 한글 "가"는 UTF-8에서 3바이트(EA B0 80)이므로%EA%B0%80이 된다.
브라우저 주소창에서는 한글이 잘 보인다. 하지만 주소를 복사해서 다른 곳에 붙여넣으면 인코딩된 상태로 나온다. 이 차이 때문에 "깨졌다"고 느끼는 것이다.
encodeURI와 encodeURIComponent 차이
JavaScript에서 URL을 인코딩할 때 쓰는 함수가 두 가지인데, 용도가 다르다.
| 함수 | 인코딩 대상 | 보존하는 문자 | 용도 |
|---|---|---|---|
encodeURI | 비ASCII 문자만 | : / ? & = # @ | 전체 URL 인코딩 |
encodeURIComponent | 거의 모든 특수문자 | 알파벳, 숫자, - _ . ~ | 쿼리 파라미터 값 인코딩 |
주의 전체 URL에 encodeURIComponent를 쓰면://이나/까지 인코딩되어 주소 자체가 망가진다. 파라미터 값에만 써야 한다.
깨진 URL 복원하는 법
누군가 보내준 링크가 %EC%9D%B8%EC%BD%94%EB%94%A9처럼 되어 있으면 읽을 수가 없다. 이럴 때 디코딩을 하면 원래 한글이 복원된다.
방법은 간단하다. URL 인코딩 변환기에서 디코딩 모드를 선택하고 해당 문자열을 붙여넣으면 된다. 입력하는 즉시 원래 텍스트가 나오고, 입출력 크기 비교까지 표시해 준다. 반대로 한글 URL을 인코딩해야 할 때도 모드만 바꾸면 바로 변환할 수 있다.
실무에서 자주 겪는 상황
- API 호출: 쿼리 파라미터에 한글 검색어를 넣을 때 인코딩하지 않으면 400 에러가 난다
- 메일/메신저 공유: 한글이 포함된 위키, 노션 링크를 보내면 중간에 끊겨서 접속이 안 된다
- 웹 크롤링: 수집한 URL에 인코딩된 한글이 섞여 있으면 중복 체크가 꼬인다
- 리다이렉트 설정: 서버에서 한글 경로를 인코딩하지 않으면 301/302 리다이렉트가 실패한다
인코딩 관련 흔한 실수
가장 많은 실수는 이중 인코딩이다. 이미 인코딩된 문자열을 한 번 더 인코딩하면 %25EA%25B0%2580처럼 퍼센트 기호까지 인코딩되어 복구가 어려워진다. 인코딩 전에 원본이 이미 인코딩 상태인지 확인하는 습관이 필요하다.
두 번째는 공백 처리다. URL에서 공백은 %20으로 인코딩하는 게 표준이지만, HTML 폼에서는 +로 바꾸는 경우도 있다. 서버 쪽에서 둘을 다르게 처리하면 문제가 생긴다.
URL 깨짐은 원리를 알면 단순한 문제다. 인코딩이 필요한 상황인지, 디코딩이 필요한 상황인지만 구분하면 된다.