URL 인코딩·디코딩
텍스트를 URL에 넣어도 안전하게 바꾸거나, %20 같은 시퀀스를 읽을 수 있는 문자로 되돌립니다. 브라우저 자체의 encodeURIComponent, encodeURI, decodeURIComponent를 쓰고, 쿼리 매개변수를 표로 정리하며, 서버로 아무것도 보내지 않습니다.
0자 · 0단어 · 0줄
0자 · 0단어 · 0줄
이 브라우저 탭 안에서만 처리됩니다. 입력한 텍스트는 업로드되거나 저장되지 않습니다.
함수별로 이스케이프하는 문자
브라우저 함수로 직접 계산한 결과입니다. encodeURIComponent는 영문자, 숫자와 다음 기호는 그대로 둡니다. ! ' ( ) * - . _ ~
| 문자 | encodeURIComponent | encodeURI |
|---|---|---|
(공백) | %20 | %20 |
! | ! | ! |
" | %22 | %22 |
# | %23 | # |
$ | %24 | $ |
% | %25 | %25 |
& | %26 | & |
' | ' | ' |
( | ( | ( |
) | ) | ) |
* | * | * |
+ | %2B | + |
, | %2C | , |
/ | %2F | / |
: | %3A | : |
; | %3B | ; |
= | %3D | = |
? | %3F | ? |
@ | %40 | @ |
[ | %5B | %5B |
] | %5D | %5D |
{ | %7B | %7B |
} | %7D | %7D |
| | %7C | %7C |
\ | %5C | %5C |
^ | %5E | %5E |
` | %60 | %60 |
< | %3C | %3C |
> | %3E | %3E |
~ | ~ | ~ |
- | - | - |
_ | _ | _ |
. | . | . |
é | %C3%A9 | %C3%A9 |
€ | %E2%82%AC | %E2%82%AC |
😀 | %F0%9F%98%80 | %F0%9F%98%80 |
퍼센트 인코딩과 RFC 3986의 예약 문자
URL에는 제한된 ASCII 문자만 들어갈 수 있습니다. URI 문법을 정한 2005년 명세인 RFC 3986은 이를 두 그룹으로 나눕니다. 비예약 문자인 A–Z, a–z, 0–9와 네 기호 - . _ ~는 인코딩할 필요가 없습니다. 예약 문자에는 맡은 역할이 있습니다. 일반 구분자 : / ? # [ ] @는 스킴, 호스트, 경로, 쿼리, 프래그먼트를 나누고, 하위 구분자 ! $ & ' ( ) * + , ; =는 그 안의 항목을 나눕니다. 쿼리 문자열의 &와 =가 그 예입니다. 그 밖의 모든 문자와 일반 데이터로 쓰인 예약 문자는 퍼센트 인코딩해야 합니다.
퍼센트 인코딩은 바이트 하나를 % 뒤에 16진수 두 자리로 적습니다. 텍스트는 먼저 UTF-8로 바뀌므로 공백은 %20, é(2바이트)는 %C3%A9, 이모지는 %XX 네 묶음이 됩니다. 한글 한 글자는 3바이트이므로 %XX 세 묶음이 됩니다. 그래서 "café & bar" 검색어는 링크에서 caf%C3%A9%20%26%20bar가 됩니다. 서버가 &를 새 매개변수의 시작으로 읽지 않도록 인코딩한 것입니다.
encodeURIComponent, encodeURI, 디코딩
encodeURIComponent는 쿼리 값, 경로 조각, 매개변수로 넘기는 리디렉션 URL처럼 한 부분을 인코딩할 때 알맞습니다. 비예약 문자와 ! ' ( ) *를 뺀 모든 문자를 이스케이프하며, 이 다섯 기호는 역사적인 이유로 JavaScript가 그대로 둡니다. encodeURI(전체 URL)는 입력이 이미 완전한 주소라고 보고 예약 문자를 그대로 두므로, https://example.com/a b?q=1에서는 공백만 인코딩됩니다. 매개변수 값에 encodeURI를 쓰는 것은 전형적인 버그입니다. 값 안의 &나 #가 그대로 남아 URL을 망가뜨립니다.
디코딩은 두 함수를 모두 되돌립니다. GET으로 제출하는 HTML 폼은 예전 방식인 application/x-www-form-urlencoded 형식을 쓰며, 여기서는 공백을 %20이 아니라 +로 적습니다. 이런 경우에는 +를 공백으로 처리(폼 인코딩)를 선택해 두고, 전화번호처럼 플러스 기호 자체가 중요할 때는 해제하세요. 입력에 16진수 두 자리가 따라오지 않는 %가 있거나 바이트가 올바른 UTF-8이 아니면, 추측하지 않고 명확한 메시지와 함께 디코딩을 멈춥니다. 텍스트에 쿼리 문자열이 있으면 매개변수가 디코딩되어 도구 아래 표에 나타납니다. URL에 바이너리 데이터를 넣을 때는 보통 Base64url을 대신 씁니다.
자주 묻는 질문
- URL의 공백은 %20인가요, 플러스 기호인가요?
- 경로에서, 그리고 RFC 3986 기준으로 공백은 %20입니다. + 표기는 HTML 폼 방식으로 인코딩한 쿼리 문자열 안에서만 공백을 뜻하므로, 어디서나 안전한 선택은 %20입니다.
- URL에 %2520이 들어간 이유는 무엇인가요?
- 두 번 인코딩되었기 때문입니다. 첫 번째에서 공백이 %20이 되었고, 두 번째에서 % 자체가 %25로 인코딩되었습니다. 한 번 디코딩해 여분의 층을 걷어 내고, 코드에서는 값을 한 곳에서만 인코딩하세요.
- 퍼센트 인코딩이 전혀 필요 없는 문자는 무엇인가요?
- RFC 3986의 비예약 문자입니다. 대소문자 A부터 Z까지의 영문자, 0부터 9까지의 숫자, 하이픈, 마침표, 밑줄, 물결표입니다.
- URL에 한글 같은 비영어 문자를 인코딩 없이 넣을 수 있나요?
- 브라우저는 그대로 보여 주지만, 실제 전송할 때는 경로나 쿼리의 ASCII 외 문자가 모두 퍼센트 인코딩된 UTF-8로 보내집니다. 도메인 이름은 별도의 체계인 Punycode를 써서 xn-- 레이블로 바뀝니다.
- 디코딩할 때 잘못된 시퀀스라고 나오는 이유는 무엇인가요?
- "100%"처럼 16진수 두 자리가 따라오지 않는 %가 텍스트에 있거나, 바이트를 디코딩한 결과가 올바른 UTF-8이 아니기 때문입니다. 디코딩하기 전에 홀로 있는 % 기호를 %25로 인코딩하세요.