URL 인코딩 · 디코딩

주소에 넣을 수 없는 글자를 %XX 형태로 바꾸거나 되돌립니다. 전체 주소를 넣을 때와 질의 값 한 조각을 넣을 때 남겨 두는 글자가 다르므로, 어느 쪽인지 골라서 씁니다.

대상

넣은 것은 기기를 벗어나지 않습니다. 브라우저 안에서만 처리하고 어디에도 보내거나 저장하지 않습니다.

퍼센트 인코딩이 하는 일

주소에는 ASCII 의 일부만 들어갈 수 있습니다. 나머지는 UTF-8 바이트로 바꾼 뒤 바이트마다 % 와 16진수 두 자리로 적습니다. 한글 한 자는 3바이트라 가 는 %EA%B0%80 아홉 글자가 됩니다. 알파벳·숫자와 -·_·.·~ 는 어디서도 바뀌지 않고, 공백은 %20 입니다. 주소창에는 한글이 보여도 브라우저가 보내는 것은 이 꼴이라, 복사해 온 주소가 % 투성이인 것이 그 때문입니다.

`encodeURI` 와 `encodeURIComponent`

이 화면의 두 방식은 브라우저의 이 두 함수 그대로입니다. 전체 주소는 : / ? # & = + $ , ; 를 남기고, 조각은 그것까지 바꿉니다. 둘 다 ! ' ( ) * 는 남겨 두는데, 규격상 예약 문자라 엄격한 서버가 다르게 읽을 수 있습니다. 질의 값에 & 나 = 가 든 채로 전체 주소 방식을 쓰면 그 자리에서 값이 끊깁니다 — 값 하나를 넣을 때는 조각을 쓰세요.

되돌릴 때 `+` 는 공백이 됩니다

폼 전송 방식은 공백을 + 로 적으므로, 되돌릴 때 + 를 먼저 공백으로 바꾼 뒤 풉니다. 값 안에 진짜 더하기가 있었다면 %2B 로 적혀 있어야 살아남습니다. %E0 처럼 바이트가 모자라거나 %zz 처럼 16진수가 아닌 것은 풀 수 없다고 돌려줍니다 — 중간에서 잘린 주소가 대개 이렇습니다.

되돌릴 때는 방식을 고르지 않습니다

전체 주소와 값 조각의 구분은 인코딩할 때만 씁니다. 되돌리기는 늘 조각 방식이라 %2F·%3F·%26 도 모두 글자로 돌아오고, 전체 주소를 넣어도 구분자는 원래 글자이니 결과가 다시 주소로 읽힙니다. 다만 + 를 공백으로 바꾸는 규칙도 늘 적용되어, 경로에 든 진짜 더하기 — /c++ — 는 /c 가 됩니다. 폼 값이 아닌 주소를 되돌렸는데 더하기가 사라졌다면 그것입니다.

`%` 자체도 바뀝니다

어느 방식이든 % 는 남겨 두는 글자가 아니라 %25 로 바꿉니다. 이미 인코딩된 %20 을 다시 넣으면 %2520 이 되는데, 링크를 주고받다 두 번 감싸이는 것이 바로 이 길입니다. 인코딩은 이렇게 몇 겹이든 쌓이고 되돌리기는 한 번에 한 겹만 벗기니, %25 가 보이면 한 번 더 되돌리세요.

자주 묻는 질문

전체 주소와 조각이 뭐가 다른가요?

전체 주소로 처리하면 : / ? & = 같은 구분자를 그대로 둡니다. 조각으로 처리하면 그것까지 바꿉니다. 질의 값에 & 가 들어 있는데 전체 주소로 처리하면 거기서 값이 잘려 버립니다 — 값을 넣을 때는 조각 쪽을 쓰세요.

주소 전체와 값 한 조각이 왜 다른가요?

? & / 같은 글자는 주소에서 자리를 나누는 뜻을 갖습니다. 주소 전체를 넘길 때 그것까지 바꿔 버리면 주소가 망가지고, 반대로 질의 값 한 조각을 넘길 때 안 바꾸면 값 안의 & 가 다음 항목의 시작으로 읽힙니다. 그래서 두 가지를 갈라 둡니다.

공백이 `+` 로 바뀌어야 하는 것 아닌가요?

자리에 따라 다릅니다. 주소의 경로에서는 %20 이 맞고, 폼을 전송할 때 쓰는 방식에서는 공백이 + 가 됩니다. 받는 쪽이 폼 방식으로 읽는데 %20 을 보내면 그대로 남기도 하니, 어느 쪽으로 받는지 확인하세요.

두 번 인코딩된 값은 어떻게 되돌리나요?

%2520 처럼 %25 가 보이면 두 번 감싼 것입니다. 디코딩을 한 번 더 돌리면 됩니다 — 링크를 주고받다 중간에서 한 번 더 감싸는 일이 흔합니다.

한글 도메인은 어떻게 하나요?

여기서는 다루지 않는 편이 맞습니다. 퍼센트 인코딩은 경로와 질의 값의 규칙이고, 호스트 이름은 IDNA 라는 다른 규칙으로 xn-- 꼴이 됩니다. 이 도구에 https://한글.kr 을 넣으면 호스트까지 % 로 바뀌어 그 주소는 열리지 않습니다. 주소창에 그대로 넣으면 브라우저가 알아서 바꿉니다.

붙여넣은 코드가 서버로 가나요?

가지 않습니다. 브라우저 안에서만 처리하고 어디에도 보내거나 저장하지 않습니다. 사내 설정 파일이나 운영 쿼리처럼 밖으로 내보내기 곤란한 것도 그래서 쓸 수 있습니다. 인터넷을 끊고도 동작합니다.