URL 인코더 / 디코더
URL, 쿼리 파라미터, 경로 세그먼트에 안전하게 쓸 수 있도록 문자열을 퍼센트 인코딩하거나 디코딩합니다.
- 인코딩하거나 디코딩할 문자열을 위의 입력칸에 붙여 넣으세요.
- 쿼리 값이나 경로 세그먼트 하나라면 Component를, 일부 안전하지 않은 문자만 포함된 전체 URL이라면 전체 URL 모드를 선택하세요.
- 인코딩 또는 디코딩 버튼을 누르면 결과가 입력칸의 내용을 대체합니다.
- 결과를 복사하거나, 지우기로 처음부터 다시 시작하세요.
어떤 도구인가요?
URL(퍼센트) 인코딩은 URL에서 안전하지 않거나 의미가 모호한 문자를 % 뒤에 해당 문자의 UTF-8 바이트 값을 16진수로 붙인 형태로 바꿉니다. Component 모드는 encodeURIComponent()를 사용해 모든 예약 문자를 인코딩하므로 쿼리 문자열이나 경로에 값으로 넣을 때 적합합니다. 전체 URL 모드는 encodeURI()를 사용해 :/?#&= 처럼 URL 구조를 이루는 문자는 그대로 둡니다.
예시
입력:
hello world & café / 日本語 Component로 인코딩:
hello%20world%20%26%20caf%C3%A9%20%2F%20%E6%97%A5%E6%9C%AC%E8%AA%9E 전체 URL로 인코딩:
hello%20world%20&%20caf%C3%A9%20/%20%E6%97%A5%E6%9C%AC%E8%AA%9E 전체 URL 모드에서는 &와 /가 URL 구조 상 의미를 가지기 때문에 그대로 남아 있는 점에 주의하세요.
자주 겪는 문제와 해결법
대부분의 인코딩 문제는 모드를 잘못 고르거나 같은 입력을 두 번 돌릴 때 생깁니다. 아래는 가장 자주 보이는 사례들이에요.
- 쿼리 값에 encodeURI를 쓰는 경우. encodeURI("a&b=c")는 a&b=c 그대로를 돌려 주고, 쿼리 문자열이 깨져요. 값에는 Component 모드(encodeURIComponent)를 쓰세요.
- 이중 인코딩. hello%20world를 한 번 더 인코딩하면 hello%2520world가 됩니다. 먼저 디코딩하거나, 한 단계를 건너뛰세요.
- #를 빠뜨리는 경우. 쿼리 값 안의 #는 %23으로 인코딩하지 않으면 프래그먼트 시작으로 해석됩니다.
- + 기호 혼동. +는 폼 인코딩(application/x-www-form-urlencoded) 본문에서는 공백을 뜻하지만, URL 경로나 쿼리에서는 그냥 + 문자입니다. 쿼리 값에 실제 + 기호를 보내려면 %2B로 인코딩하세요.
- 잘못된 퍼센트 시퀀스. 인코딩되지 않은 % 하나가 있으면 decodeURIComponent가 "URI malformed" 오류를 냅니다. %는 %25로 인코딩하거나, 디코딩 전에 홀로 있는 %를 제거하세요.
- UTF-8과 Latin-1 레거시 서버. 이 도구는 항상 UTF-8을 사용합니다. 아주 오래된 시스템은 Latin-1 / windows-1252를 기대하기도 해요 — 그런 환경에서 é는 %C3%A9가 아니라 %E9입니다. 글자가 깨져 보인다면 상대 쪽이 UTF-8을 쓰지 않는 것이에요.
자주 묻는 질문
encodeURI와 encodeURIComponent의 차이는 무엇인가요?
encodeURIComponent는 문자·숫자와 -_.!~*'() 외의 모든 문자를 이스케이프하기 때문에 개별 쿼리 값이나 경로 세그먼트에 안전합니다. encodeURI는 :/?#&= 처럼 URL에 예약된 문자는 그대로 두므로, 이미 구조를 갖춘 URL 전체를 인코딩할 때 씁니다. 실무에서는 95%의 경우 Component를 쓰고, 공백이나 유니코드만 살짝 섞인 거의 완성된 URL에만 전체 URL을 쓰세요.
쿼리 문자열에서 실제로 인코딩해야 하는 문자는 무엇인가요?
값 안에서는 쿼리 구분자인 &와 =를 반드시 인코딩해야 합니다(그렇지 않으면 구분자처럼 보여요). 공백은 %20 또는 +가 되고, 프래그먼트 구분자 #도 인코딩해야 합니다. 그 외에 /, ?, ASCII가 아닌 모든 문자, 제어 문자도 포함돼요. encodeURIComponent는 이 모두를 처리하고, encodeURI는 &, =, /, ?, #는 URL 구조 문자라서 그대로 둡니다.
왜 URL이 이중으로 인코딩되나요?
이중 인코딩은 이미 인코딩된 값을 한 번 더 인코딩할 때 생겨요. 공백이 %20이 된 다음, 그 %가 다시 %25가 되어 %2520이 됩니다. 보통은 이미 인코딩된 URL을 encodeURIComponent에 또 넣거나, 여러분의 수동 인코딩 위에 프레임워크가 자동으로 한 번 더 인코딩할 때 발생해요. 한 번 디코딩하고 깔끔하게 다시 인코딩하거나, 한 단계를 건너뛰세요.
이모지나 악센트가 있는 글자 같은 비-ASCII 문자는 어떻게 처리되나요?
JavaScript의 인코더는 비-ASCII 문자를 먼저 UTF-8 바이트로 바꾸고, 각 바이트를 퍼센트 인코딩합니다. 그래서 é는 %C3%A9(2바이트)가 되고, 😀 같은 이모지는 %F0%9F%98%80(4바이트)가 됩니다. 디코딩은 그 반대로 동작해요. 이것은 RFC 3986 표준 동작이고, 최신 서버라면 어디서든 잘 작동합니다.
왜 디코딩이 "URI malformed" 오류로 실패하나요?
decodeURIComponent는 잘못된 퍼센트 시퀀스를 만나면 예외를 던집니다 — 두 자리 16진수가 따라붙지 않은 % 하나(예: %ZZ나 그냥 %)이거나, 유효하지 않은 UTF-8 바이트 시퀀스(예: 이어지는 바이트 없이 %C3만 있는 경우)일 때예요. 흔한 원인은 인코딩되지 않은 %가 입력에 그대로 들어가 있거나, 이미 한 번 디코딩된 문자열에 아직 % 기호가 남아 있는 경우입니다.
공백은 +로, 아니면 %20으로 바꿔야 하나요?
실제로는 둘 다 쓰입니다. %20은 경로·쿼리·프래그먼트 어디에서나 안전해요. +를 공백으로 해석하는 단축 표기는 HTML 폼이 보낼 때 쓰는 application/x-www-form-urlencoded 형식에서만 통합니다. 이 도구는 encodeURIComponent를 따르기 때문에 %20을 사용해요. 꼭 +가 필요하다면, 인코딩한 뒤에 %20을 +로 바꾸면 됩니다.