URL 인코딩 디코딩
쿼리 값 하나나 경로 세그먼트에 알맞습니다. 영문자, 숫자, - _ . ! ~ * ' ( )를 제외한 모든 문자를 인코딩하며 encodeURIComponent와 같습니다.
위에 URL을 붙여 넣으세요. 각 부분과 파라미터가 여기에 표시되며 바로 편집할 수 있습니다.
쿼리 파라미터
이 URL에는 쿼리 파라미터가 없습니다.
프래그먼트 파라미터
모든 작업은 브라우저 안에서 실행되며 붙여 넣은 내용은 업로드되지 않습니다. URL에는 토큰이나 세션 ID가 들어 있는 경우가 많기 때문에 중요한 점입니다.
URL 인코딩과 디코딩을 입력하는 즉시 온라인에서 할 수 있습니다. 공백, 악센트 문자, 한글, &나 ? 같은 기호를 %20 같은 퍼센트 인코딩 시퀀스로 바꿔 주고, 다시 읽을 수 있는 텍스트로 되돌려 줍니다. 두 번째 탭은 URL 파서입니다. 주소를 프로토콜, 호스트, 경로, 쿼리 파라미터로 나누어 보여 주고, 파라미터를 수정하거나 끄거나 추적 태그를 지울 수 있으며, 올바르게 인코딩된 URL을 다시 만들어 줍니다. 모든 작업은 브라우저 안에서 이루어집니다.
URL 인코딩과 디코딩 방법
- 인코딩 / 디코딩 탭의 입력란에 텍스트를 입력하거나 붙여 넣습니다. 결과는 키를 누를 때마다 갱신됩니다.
- 방향을 고릅니다. 인코딩은 텍스트를 URL에 안전하게 쓸 수 있게 바꾸고, 디코딩은
caf%C3%A9%20au%20lait를café au lait로 되돌립니다. 비어 있는 입력란에%20같은 시퀀스가 들어 있는 텍스트를 붙여 넣으면 도구가 스스로 디코딩으로 전환하며(인코딩하기를 누르면 다시 돌아갑니다), 디코딩 모드에서 인코딩이 필요한 일반 텍스트를 붙여 넣으면 같은 방식으로 인코딩으로 전환하고 디코딩하기 버튼이 나타납니다. - 인코딩할 때는 인코딩 대상에서 텍스트의 종류를 고릅니다(다음 항목 참고). 기본값인 파라미터 값은 쿼리 값 하나를 인코딩할 때 알맞습니다.
- 복사는 결과를 클립보드에 복사합니다. 바꾸기는 결과를 입력란으로 옮기고 방향을 반대로 바꿉니다. 왕복 검사를 빠르게 할 수 있는 방법입니다. 방금 인코딩한 것을 디코딩하면 원래 텍스트가 그대로 나와야 합니다.
도구가 바꾼 문자는 결과에서 모두 강조 표시됩니다. 마우스를 올리면 그 문자, 유니코드 코드 포인트, 바이트를 볼 수 있습니다. 예를 들면 é U+00E9 %C3%A9입니다. 입력란 아래에는 문자 수, UTF-8 바이트 수, 인코딩된 문자 수(또는 디코딩된 문자 수)가 표시됩니다. 예시 불러오기는 가격: 50 % 할인, 커피 & 케이크? 좋아요!라는 문장을 불러옵니다. 이 문장은 27자이지만 UTF-8로는 51바이트인데, 한글 음절 12개가 각각 3바이트를 차지하고 나머지 ASCII 문자는 1바이트이기 때문입니다.
인코딩할 때 줄마다 따로를 켜면 각 줄을 따로 인코딩하고 줄바꿈은 그대로 둡니다. 값이나 링크 목록에 알맞은 방식입니다. 이 옵션이 꺼져 있으면 줄바꿈도 인코딩되어 %0A가 됩니다. 텍스트가 파라미터가 있는 URL이면 부분으로 나누기 버튼이 나타나며, 누르면 그 주소가 파서 탭에서 열립니다.
URL 파라미터, 전체 URL, 폼 데이터 인코딩
모든 문자를 어디서나 인코딩해야 하는 것은 아닙니다. 슬래시는 경로에서는 폴더를 구분하지만 파라미터 값 안에서는 평범한 데이터입니다. 그래서 올바른 결과는 무엇을 인코딩하느냐에 따라 달라집니다. 인코딩 대상에는 네 가지 모드가 있습니다.
- 파라미터 값은 JavaScript의
encodeURIComponent처럼 동작하며 쿼리 값 하나나 경로 세그먼트에 알맞습니다. 영문자, 숫자,- _ . ! ~ * ' ( )를 제외한 모든 문자를 인코딩하므로 값 안의&,=,/,?가 URL을 깨뜨리지 못합니다.café & crème를 인코딩하면caf%C3%A9%20%26%20cr%C3%A8me가 되며,q=뒤에 바로 붙여 쓸 수 있습니다. - 전체 URL은 정리만 하면 되는 완전한 주소에 씁니다. 공백, ASCII가 아닌 문자, 제어 문자, 백틱,
" < > \ ^ { | }를 인코딩하고, URL의 구조를 이루는: / ? # [ ] @ ! $ & ' ( ) * + , ; =는 그대로 둡니다. 그래서https://example.com/search?q=café au lait&lang=fr는https://example.com/search?q=caf%C3%A9%20au%20lait&lang=fr가 됩니다. 이미 인코딩된 시퀀스는 그대로 두고, 홀로 있는%는%25가 됩니다. 이 점이 JavaScript의encodeURI와 다릅니다.encodeURI는 이미 있는%20을%2520으로 바꾸고,http://[2001:db8::1]:8080/같은 IPv6 주소의 대괄호도 인코딩합니다. - 폼 데이터는 HTML 폼과
URLSearchParams가 만드는 application/x-www-form-urlencoded(영어) 형식을 따릅니다. 공백은+가 되고, 영문자, 숫자,* - . _만 인코딩되지 않으므로! ' ( ) ~도 인코딩됩니다. - 엄격한 RFC 3986은 RFC 3986(영어)의 비예약 문자인 영문자, 숫자,
- . _ ~만 그대로 둡니다. OAuth 1.0(RFC 5849)과 AWS Signature Version 4는 바로 이 형식을 요구합니다. 양쪽이!나*를 똑같이 인코딩해야만 서명이 일치하기 때문입니다.
같은 문자가 모드마다 어떻게 달라지는지 보여 주는 표입니다.
| 문자 | 파라미터 값 | 전체 URL | 폼 데이터 | 엄격한 RFC 3986 |
|---|---|---|---|---|
| 공백 | %20 | %20 | + | %20 |
& | %26 | & | %26 | %26 |
/ | %2F | / | %2F | %2F |
+ | %2B | + | %2B | %2B |
~ | ~ | ~ | %7E | ~ |
! | ! | ! | %21 | %21 |
* | * | * | * | %2A |
é | %C3%A9 | %C3%A9 | %C3%A9 | %C3%A9 |
텍스트는 항상 UTF-8로 인코딩되고 16진수 숫자는 항상 대문자로 쓰입니다. 입력에 이미 %20 같은 시퀀스가 들어 있으면 안내 문구가 나타나고 디코딩하기 버튼이 제공되므로, 실수로 두 번 인코딩하는 일을 막을 수 있습니다.
쿼리 파라미터에 JSON을 넣으려면 JSON 포매터에서 JSON을 한 줄로 압축한 뒤 파라미터 값으로 인코딩하세요. {"id":7,"tags":["a","b"]}는 %7B%22id%22%3A7%2C%22tags%22%3A%5B%22a%22%2C%22b%22%5D%7D가 됩니다. 반대로도 쓸 수 있습니다. 여기서 파라미터를 디코딩한 다음 그쪽에서 포맷하면 됩니다.
URL 디코딩 문제: 더하기 기호, %2520, 깨진 시퀀스
디코딩은 대개 문제없이 되지만 사람들이 자주 걸려 넘어지는 경우가 네 가지 있습니다. 도구는 오류를 내며 멈추는 대신 각각을 처리합니다.
- 더하기 기호는 폼 데이터와 대부분의 쿼리 문자열에서 공백을 뜻합니다. +를 공백으로 디코딩은 기본으로 켜져 있어서
caf%C3%A9+au+lait는café au lait로 디코딩됩니다. 전체 URL에서는 경로의 더하기 기호가 평범한 문자이므로?뒤의 더하기 기호만 공백으로 취급합니다. 더하기 기호를 말 그대로의+로 써야 한다면 이 옵션을 끄세요.%2B로 인코딩된 더하기는 항상 더하기 기호로 남습니다. - 이중 인코딩은 코드의 두 계층이 같은 값을 각각 인코딩할 때 생기며, RFC 3986은 이를 명시적으로 경고합니다.
%가 각각%25가 되어 공백이%20에서%2520으로 바뀝니다. 디코딩한 결과에 아직%20같은 시퀀스가 있으면 도구가 텍스트가 두 번 인코딩된 것 같다고 알리고 다시 디코딩 버튼을 제공합니다. - 잘못된 시퀀스는
100%나%G1처럼%뒤에 16진수 두 자리가 오지 않는 경우로, JavaScript의decodeURIComponent가 URIError를 던집니다. 이 도구는 그런 시퀀스를 그대로 두고 빨간색으로 표시하며 개수를 센 다음, 나머지 텍스트는 디코딩합니다. - 오래된 Latin-1 링크는 UTF-8 이전 시대에서 온 것으로, 일부 사이트가
é를%E9라는 한 바이트로 인코딩하던 때의 링크입니다.caf%E9는 올바른 UTF-8이 아니어서decodeURIComponent는 실패하고, Python의unquote는caf뒤에 대체 문자 U+FFFD를 돌려줍니다. 도구는 이런 바이트를 Windows-1252로 읽어caf%E9를café로 디코딩하고 그 사실을 안내 문구로 알려 줍니다.
디코딩된 텍스트 안의 탭이나 널 바이트 같은 제어 문자는 ␉, ␀ 같은 눈에 보이는 기호로 표시되지만, 복사는 실제 텍스트를 복사합니다.
URL 파서: URL을 나누고 쿼리 파라미터 편집하기
URL 분석 및 편집 탭의 URL 입력란에 주소를 붙여 넣으면 프로토콜, 호스트, 포트, 경로, 프래그먼트로 나뉘고, URL에 들어 있으면 사용자 이름과 비밀번호도 표시됩니다. 값은 디코딩된 상태로 보여 주므로, 이 탭은 URL 파라미터를 디코딩하는 가장 빠른 방법이기도 합니다. %EB%9F%AC%EB%8B%9D+%EC%8B%A0%EB%B0%9C이 아니라 러닝 신발로 읽을 수 있습니다. 편집은 양방향으로 됩니다. 주소창이나 Postman의 파라미터 표처럼, 한 항목을 바꾸면 URL이 곧바로 올바르게 인코딩되어 다시 만들어지고, URL을 바꾸면 모든 부분을 다시 읽습니다. 건드리지 않은 부분은 한 글자도 바뀌지 않고 그대로 남습니다.
쿼리 파라미터 표에는 모든 파라미터가 이름과 값과 함께 나열됩니다. URL에 포함의 체크를 해제하면 파라미터를 지우지 않고 URL에서만 뺄 수 있어서, 요청을 망가뜨리는 파라미터를 찾을 때 유용합니다. 파라미터 추가, 파라미터 삭제, A부터 Z까지 정렬은 이름 그대로 동작합니다. tag=a&tag=b처럼 반복되는 이름과 ?debug처럼 값이 없는 이름도 그대로 유지됩니다. 파라미터의 공백은 공백을 %20으로 쓸지 +로 쓸지 정하며, 기본값은 붙여 넣은 URL을 따릅니다.
로그인과 결제 링크에는 파라미터 안에 또 다른 URL이 들어 있는 경우가 많습니다. 그 URL 자신의 ?와 &가 바깥쪽 것과 섞이지 않도록 인코딩되어 있습니다.
https://auth.example.com/authorize?client_id=abc&redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback%3Ftab%3D2
값 자체가 URL인 경우, 대개 redirect_uri, return, url, next에서 안쪽 URL 편집 버튼이 나타납니다. 안쪽 주소 https://app.example.com/callback?tab=2는 자신의 부분과 파라미터를 가진 별도의 단계로 열리고, 이동 경로(메인 URL › redirect_uri)로 돌아갈 수 있으며, 모든 변경은 인코딩되어 바깥쪽 URL에 반영됩니다. 메인 URL 복사는 결과를 복사합니다. 이 방식은 여러 단계 깊이까지 동작합니다.
# 뒤의 부분이 OAuth 암시적 흐름의 #access_token=...&state=...나 싱글 페이지 앱 라우트의 #/search?q=shoes처럼 파라미터 형태이면, 두 번째 표인 프래그먼트 파라미터에도 목록이 표시됩니다.
파서는 문제도 짚어 줍니다. 브라우저가 상대 링크로 취급하는 프로토콜 없는 URL, 0부터 65535 범위를 벗어난 포트, 공백, 악센트 문자, ", <처럼 반드시 인코딩해야 하는 문자가 그렇습니다. 마지막 경우는 이 문자들 인코딩으로 한 번에 고칠 수 있습니다. a=1&b=2처럼 주소가 없는 텍스트는 쿼리 문자열로 읽습니다. 국제화 도메인 이름의 경우 DNS와 브라우저가 사용하는 퓨니코드 형태를 보여 주므로 münchen.de는 xn--mnchen-3ya.de가 되고, xn--로 시작하는 도메인은 읽을 수 있는 형태로 표시됩니다.
URL 복사는 완성된 주소를 복사하고, 열기는 새 탭에서 엽니다(http와 https 링크만 해당). JSON으로 복사는 파라미터를 JSON 객체로 줍니다. 반복되는 이름은 배열로 모입니다.
URL에서 UTM 등 추적 파라미터 제거하기
뉴스레터, 광고, 소셜 네트워크의 링크에는 방문자가 어디서 왔는지 사이트에 알려 주는 용도로만 쓰이는 파라미터가 붙어 있습니다. UTM 파라미터인 utm_source, utm_medium, utm_campaign, utm_term, utm_content는 구글 애널리틱스의 전신인 Urchin에서 유래했습니다. fbclid(Facebook), gclid(Google Ads), msclkid(Microsoft Advertising) 같은 클릭 ID는 플랫폼이 직접 덧붙입니다.
파서는 이런 파라미터에 추적 태그를 붙이고, 추적 제거 (n) 버튼은 이를 한꺼번에 삭제합니다. 모든 utm_* 파라미터 외에도 ttclid(TikTok), mc_cid(Mailchimp), _hsenc(HubSpot) 등 20개가 넘는 파라미터를 알아봅니다. 페이지에 필요한 파라미터는 그대로 남습니다. 예시 불러오기로 불러온 쇼핑 링크에서 **추적 제거 (4)**는 utm_source, utm_medium, utm_campaign, fbclid를 지우고 q, size, return과 #reviews 프래그먼트는 유지합니다.
QR 코드에 넣을 링크는 여기서 먼저 정리해 두면 좋습니다. 추적 파라미터를 뺀 링크는 더 짧고, 링크가 짧으면 QR 코드가 덜 촘촘해져서 스캔하기 쉽습니다.
퍼센트 인코딩이란 무엇이며 문자가 %XX가 되는 원리
퍼센트 인코딩은 URL 인코딩이라고도 하며, 문자를 %와 16진수 두 자리로 적는 방식입니다. URL에는 제한된 ASCII 문자만 쓸 수 있고, 그중 일부는 역할이 있습니다. ?는 쿼리를 시작하고, &는 파라미터를 구분하고, #은 프래그먼트를 시작합니다. RFC 3986은 이런 문자를 예약 문자라고 부릅니다(: / ? # [ ] @와 ! $ & ' ( ) * + , ; =). 영문자, 숫자, - . _ ~는 비예약 문자여서 인코딩할 필요가 전혀 없습니다. 그 밖의 모든 문자와, 일반 데이터로 쓰이는 예약 문자는 인코딩됩니다.
ASCII가 아닌 문자는 먼저 UTF-8 바이트로 바뀌고, 바이트마다 %XX가 하나씩 붙습니다.
é는 U+00E9이며 UTF-8에서는 C3 A9 두 바이트로 저장되므로%C3%A9가 됩니다.€는 U+20AC로 3바이트이며%E2%82%AC가 됩니다.- U+1F600(활짝 웃는 얼굴) 같은 이모지는 4바이트를 차지하며
%F0%9F%98%80이 됩니다.
%c3%a9와 %C3%A9는 같은 뜻이지만 RFC 3986은 대문자를 권장하며, 도구도 대문자로 씁니다. 가장 자주 만나는 문자의 퍼센트 인코딩 표입니다.
| 문자 | 인코딩 | 문자 | 인코딩 |
|---|---|---|---|
| 공백 | %20 | + | %2B |
! | %21 | , | %2C |
" | %22 | / | %2F |
# | %23 | : | %3A |
$ | %24 | ; | %3B |
% | %25 | = | %3D |
& | %26 | ? | %3F |
' | %27 | @ | %40 |
( | %28 | [ | %5B |
) | %29 | ] | %5D |
* | %2A | 줄바꿈 | %0A |
JavaScript, Python, PHP에서의 URL 인코딩
모든 언어에 이를 위한 함수가 있으며, 차이는 주로 공백, 슬래시, ! ' ( ) * ~를 다루는 방식에 있습니다.
JavaScript에는 값용 encodeURIComponent, 전체 주소용 encodeURI, 폼 인코딩용 URLSearchParams가 있습니다.
encodeURIComponent("café & crème") // "caf%C3%A9%20%26%20cr%C3%A8me"
encodeURI("https://example.com/a b?q=café") // "https://example.com/a%20b?q=caf%C3%A9"
new URLSearchParams({ q: "café & crème" }).toString() // "q=caf%C3%A9+%26+cr%C3%A8me"
decodeURIComponent("caf%C3%A9") // "café"
decodeURIComponent는 +를 공백으로 바꾸지 않으며, 100% 같은 잘못된 시퀀스에서는 URIError를 던집니다.
Python에서는 함수가 urllib.parse에 있습니다. quote는 기본적으로 /를 그대로 두고(safe='/') 나머지는 RFC 3986 비예약 문자를 제외하고 모두 인코딩합니다. quote_plus는 공백을 +로 쓰고 /도 인코딩합니다.
from urllib.parse import quote, quote_plus, urlencode, unquote_plus
quote("café & crème/brûlée") # 'caf%C3%A9%20%26%20cr%C3%A8me/br%C3%BBl%C3%A9e'
quote("a b/c", safe="") # 'a%20b%2Fc'
quote_plus("café & crème/brûlée") # 'caf%C3%A9+%26+cr%C3%A8me%2Fbr%C3%BBl%C3%A9e'
urlencode({"q": "café & crème", "page": 2}) # 'q=caf%C3%A9+%26+cr%C3%A8me&page=2'
unquote_plus("caf%C3%A9+au+lait") # 'café au lait'
PHP에서 urlencode는 HTML 폼처럼 인코딩하며 공백을 +로 쓰고, rawurlencode는 RFC 3986을 따라 %20으로 씁니다.
urlencode("café & crème"); // "caf%C3%A9+%26+cr%C3%A8me"
rawurlencode("café & crème"); // "caf%C3%A9%20%26%20cr%C3%A8me"
rawurlencode는 엄격한 RFC 3986과 결과가 같습니다. urlencode는 *를 %2A로 인코딩한다는 점만 빼면 폼 데이터와 일치합니다.
자주 묻는 질문
URL에서 공백은 %20으로 인코딩하나요, +로 인코딩하나요?
%20은 URL의 어느 위치에서나 쓸 수 있습니다. +가 공백을 뜻하는 것은 쿼리 문자열과 폼 데이터(HTML 폼이 보내는 형식)뿐입니다. 경로에서 +는 평범한 더하기 기호이므로 /a+b는 /a+b 그대로입니다. 쿼리 값에 진짜 더하기 기호가 필요하면 %2B로 쓰세요. 이 도구에서는 폼 데이터가 공백을 +로 쓰고 나머지 세 모드는 %20으로 씁니다.
URL의 %20, %2F, %3D는 무슨 뜻인가요?
인코딩된 문자입니다. %20은 공백, %2F는 슬래시, %3D는 등호입니다. 자주 보이는 다른 것으로는 %26(&), %3F(?), %3A(:), %2C(쉼표), %27(작은따옴표)가 있습니다. 두 자리 숫자는 그 문자의 코드를 16진수로 쓴 것입니다. 악센트 문자나 한글 같은 ASCII가 아닌 문자는 %C3%A9(é)처럼 두 개에서 네 개의 쌍을 차지합니다. 문자열 전체를 디코더에 붙여 넣으면 읽을 수 있습니다.
encodeURI와 encodeURIComponent의 차이는 무엇인가요?
encodeURI는 주소 전체용이며 : / ? # & =처럼 주소의 구조를 이루는 문자는 그대로 둡니다. encodeURIComponent는 파라미터 값이나 경로 세그먼트 같은 한 부분용이며 그런 문자도 인코딩하므로 https://example.com/?a=1&b=2는 https%3A%2F%2Fexample.com%2F%3Fa%3D1%26b%3D2가 됩니다. 이 도구에서는 파라미터 값이 encodeURIComponent와 같고, 전체 URL은 encodeURI와 비슷하지만 %20 같은 기존 시퀀스를 %2520으로 바꾸지 않고 그대로 둡니다.
URL에서 UTM 파라미터를 제거하려면 어떻게 하나요?
링크를 URL 분석 및 편집 탭에 붙여 넣고 추적 제거 (n)를 누르세요. 모든 utm_* 태그와 fbclid, gclid 같은 클릭 ID가 한꺼번에 삭제됩니다. 그런 다음 URL 복사를 누르면 됩니다. 일부만 지우려면 원하지 않는 행에서 파라미터 삭제를 사용하세요.
URL 인코딩은 암호화나 Base64와 같은가요?
아닙니다. URL 인코딩은 아무것도 숨기지 않습니다. 누구나 caf%C3%A9를 café로 디코딩할 수 있으므로 비밀번호나 토큰을 보호하지 못합니다. 문자를 주소에 안전하게 쓸 수 있게 만들 뿐입니다. Base64는 바이너리 파일을 포함한 모든 데이터를 64개 문자의 문자열로 바꾸는 다른 인코딩입니다. URL에 들어간 Base64 문자열도 +, /, =를 인코딩해야 합니다. 다만 Base64 인코더 및 디코더가 만들 수 있는 URL 안전 변형을 쓰면 그럴 필요가 없습니다.
붙여 넣은 URL이 업로드되거나 저장되나요?
아닙니다. 인코딩, 디코딩, 분석은 모두 브라우저에서 실행되며 붙여 넣은 내용은 서버로 전송되지 않습니다. URL에는 액세스 토큰, 세션 ID, 비밀번호 재설정 코드가 들어 있는 경우가 많으므로 이 점이 중요합니다. 브라우저가 기억하는 것은 선택한 탭과 옵션뿐이며 텍스트는 기억하지 않습니다. 주소를 불러오는 것은 열기뿐이며, 링크를 직접 클릭할 때처럼 새 탭에서 엽니다.
프로그래머를 위한 다른 도구는 개발자 카테고리에, 한 형식을 다른 형식으로 바꾸는 도구는 변환기 카테고리에 모여 있습니다. 긴 URL 두 개, 예를 들어 정상 동작하는 API 호출과 실패하는 호출의 차이를 찾으려면 텍스트 비교 도구에 붙여 넣고 글자 단위로 비교하세요.