세 가지 방식은 무엇이 다른가
URL 인코딩이 하나가 아니라는 게 이 작업이 헷갈리는 이유입니다. 값을 주소의 어느 자리에 넣느냐에 따라 규칙이 달라집니다.
| 방식 | 쓸 때 | a/b?c는 |
|---|---|---|
| 쿼리 값 | ?q= 뒤에 들어갈 값 하나 | a%2Fb%3Fc |
| 주소 전체 | https://…로 시작하는 주소 한 줄 | a/b?c |
| 폼 전송 | HTML 폼이 보내는 application/x-www-form-urlencoded | a%2Fb%3Fc, 공백은 + |
가장 흔한 실수는 주소 전체에 "쿼리 값" 방식을 쓰는 것입니다. https://의
:와 /까지 인코딩되어 https%3A%2F%2F…가 되고, 링크가
상대 경로로 취급됩니다.
한글은 왜 %EA%B0%80처럼 길어지나
주소에는 아스키 문자만 쓸 수 있습니다. 한글은 먼저 UTF-8 바이트로 쪼개지고, 바이트 하나가
% 뒤 두 자리 16진수 하나가 됩니다. 한글 한 글자는 3바이트라 가
하나가 %EA%B0%80 아홉 글자가 됩니다.
주소창에 한글을 그대로 쳐도 되는 것은, 브라우저가 화면에는 한글로 보여 주면서 서버에는 인코딩해서 보내기 때문입니다. 그 주소를 복사해 코드에 붙이면 인코딩된 형태로 붙습니다.
공백은 %20인가 +인가
둘 다 맞지만 자리가 다릅니다. 경로(/my%20file)에서는 반드시 %20이고,
+는 공백이 아니라 진짜 더하기 기호입니다. 폼 전송 본문과 쿼리스트링에서만
+가 공백으로 해석됩니다. 애매하면 %20이 안전합니다 — 양쪽 다 통합니다.
이미 인코딩된 값을 또 인코딩하면요?
%가 %25가 되면서 이중 인코딩됩니다. %25EA%25B0%2580처럼
보이면 그 상태이고, URL 디코딩을 두 번 돌려야 원래 값이 나옵니다.
여러 줄을 한 번에 변환할 수 있나요?
됩니다. 줄바꿈은 그대로 두고 각 줄을 따로 인코딩하므로, 목록을 통째로 붙여넣어도 됩니다.