쿼리스트링의 구조
URL은 대략 스킴://호스트/경로?쿼리#프래그먼트 순서로 구성되고, 쿼리는 물음표 뒤에서 샵(#) 앞까지입니다. 쿼리 안에서는 앰퍼샌드(&)가 파라미터를 가르고 첫 번째 등호(=)가 키와 값을 가릅니다. 값 안에 등호가 또 있어도 두 번째부터는 값의 일부입니다. 이 도구는 브라우저가 내장한URLSearchParams 규칙을 그대로 따르므로, 브라우저와 자바스크립트가 읽는 결과와 같은 값을 보여 줍니다. 입력한 URL은 서버로 전송되지 않고 브라우저 안에서만 처리됩니다.
입력 형태를 인식하는 방법
- 전체 URL(
https://...,/path?x=1,?x=1): 첫 번째 물음표 뒤를 쿼리로 읽습니다. 샵(#) 뒤의 프래그먼트는 먼저 잘라냅니다. - 물음표 없는 전체 URL: 파라미터가 없는 것으로 처리합니다. 예전처럼 주소 전체를 키 하나로 읽지 않습니다.
- 쿼리스트링만(
a=1&b=2): 그대로 분해합니다. 값 안에?가 들어 있어도(예:redirect=http://a.com/?x=1) 앞부분을 잘라 먹지 않도록, 물음표 앞쪽에 등호가 있으면 쿼리스트링으로 간주합니다. - 프래그먼트 안의 파라미터(
#/page?x=1형태의 단일 페이지 앱 주소): 프래그먼트는 서버로 전송되지 않는 영역이어서 분해 대상이 아닙니다. 필요하면 샵 뒤 부분만 복사해 넣으세요.
같은 입력이 어떻게 분해되는지 (표준 동작으로 계산한 표)
아래 표는 URLSearchParams에 직접 넣어 얻은 결과입니다. 중복 키는 줄이 나뉘고, 값이 없는 키는 빈 문자열이 되며, 대괄호 표기는 해석되지 않고 키 이름에 그대로 남습니다.
| 입력 | 분해 결과 |
|---|---|
a=1&a=2&a=3 | a = "1" / a = "2" / a = "3" |
b=&c&&d=x%3Dy | b = "" / c = "" / d = "x=y" |
q=hello+world&r=hello%20world | q = "hello world" / r = "hello world" |
s=1%2B1&t=1+1 | s = "1+1" / t = "1 1" |
a[]=1&a[]=2&a[b]=3 | a[] = "1" / a[] = "2" / a[b] = "3" |
k=%2F%3F%23 | k = "/?#" |
y=100% | y = "100%" |
a=1;b=2 | a = "1;b=2" |
a=1&a=2&a=3처럼 같은 키가 반복되면 값 3개가 모두 나옵니다. 서버 프레임워크는 이를 배열로 묶기도 하고, 첫 값이나 마지막 값만 취하기도 합니다. 동작은 프레임워크마다 다르므로 받는 쪽 문서를 확인해야 합니다.a[]=1&a[]=2는 PHP나 일부 Node 라이브러리(qs 등)에서 배열이나 객체로 해석되는 관례일 뿐 URL 표준이 아닙니다. 이 도구는 키 이름a[]로 그대로 보여 줍니다.1+1의+는 폼 인코딩 규칙에서 공백이므로t=1+1의 값은1 1입니다. 진짜 더하기 문자를 보내려면%2B로 써야 합니다.- 세미콜론(;)은 구분자로 취급되지 않습니다. 과거 일부 서버가 세미콜론을 구분자로 허용했지만 현재 브라우저 표준은 앰퍼샌드만 인정합니다.
- 잘못된 퍼센트 인코딩(
100%, 불완전한 UTF-8 바이트)은 오류 없이 그대로 남거나 깨진 문자(�)로 바뀝니다. 이 도구는 그런 항목을 표 아래 요약에서 알려 줍니다.
인코딩 규칙 비교: URLSearchParams와 encodeURIComponent
이 도구의 빌더는 URLSearchParams와 같은 폼 인코딩 규칙을 쓰고, 자바스크립트의 encodeURIComponent는 조금 다릅니다. 두 방식 모두 한글은 UTF-8 바이트를 퍼센트로 표기하며(예: 한 = %ED%95%9C) 서로 읽을 수 있지만, 아래 표처럼 몇몇 문자에서 출력이 달라 서명 계산이나 캐시 키 비교에서 문제가 됩니다.
| 문자 | 빌더(URLSearchParams) | encodeURIComponent |
|---|---|---|
| 공백 | + | %20 |
| 더하기 + | %2B | %2B |
| 앰퍼샌드 & | %26 | %26 |
| 등호 = | %3D | %3D |
| 슬래시 / | %2F | %2F |
| 물음표 ? | %3F | %3F |
| 샵 # | %23 | %23 |
| 퍼센트 % | %25 | %25 |
| 작은따옴표 ' | %27 | ' |
| 여는 괄호 ( | %28 | ( |
| 느낌표 ! | %21 | ! |
| 틸드 ~ | %7E | ~ |
| 별표 * | * | * |
| 한글 한 | %ED%95%9C | %ED%95%9C |
가장 흔한 차이는 공백입니다. 폼 인코딩은 공백을 +로, encodeURIComponent는 %20으로 쓰며, 이 도구의 "공백을 %20으로" 옵션은 이 차이를 맞출 때 씁니다.+가 공백을 뜻하는 것은 쿼리(폼 인코딩) 안에서만이고, 경로(path)에서의 +는 글자 그대로의 더하기입니다. 그래서 경로 조각에는 %20이 안전합니다. 또 작은따옴표, 괄호, 느낌표, 틸드는 두 방식에서 처리가 다르므로 OAuth 1.0 서명처럼 문자 단위로 엄격한 규칙이 있는 곳에서는 해당 규격이 요구하는 인코딩을 따라야 합니다.
검산한 예시
예시 1. UTM 링크 분해. 입력 https://example.com/page?utm_source=naver&utm_medium=cpc&keyword=%ED%95%9C%EA%B8%80&id=123#top 에서 프래그먼트(#top)는 제외되고 파라미터 4개가 나옵니다.
utm_source=naverutm_medium=cpckeyword=한글id=123
예시 2. 인코딩 결과. 키·값 4쌍(utm_source=naver, keyword=한글 검색어, q=a&b=c, plus=1+1)을 넣으면 기본 모드에서는 아래와 같고, "%20" 옵션을 켜면 공백 부분만 달라집니다. 값 속의 &, =, +가 각각 %26, %3D, %2B로 바뀌어 파라미터 경계를 침범하지 않는 점을 확인하세요.
utm_source=naver&keyword=%ED%95%9C%EA%B8%80+%EA%B2%80%EC%83%89%EC%96%B4&q=a%26b%3Dc&plus=1%2B1
utm_source=naver&keyword=%ED%95%9C%EA%B8%80%20%EA%B2%80%EC%83%89%EC%96%B4&q=a%26b%3Dc&plus=1%2B1UTM 파라미터를 점검할 때
마케팅 링크에는 보통 utm_source(유입처), utm_medium(매체), utm_campaign(캠페인)에 더해 utm_term(검색어), utm_content(소재 구분)가 붙습니다. 분석 도구는 값을 대소문자까지 구분해 서로 다른 항목으로 집계하는 경우가 많으므로 naver와 Naver가 섞이지 않았는지, 값에 공백이나 한글이 들어가 보고서에서 읽기 어렵지 않은지, 같은 키가 두 번 들어가 한쪽이 무시되지 않는지를 이 도구의 표와 중복 키 안내로 점검할 수 있습니다.
흔한 실수와 한계
- 이중 인코딩: 이미 인코딩된 값을 한 번 더 인코딩하면 %25ED처럼 퍼센트가 다시 %25로 바뀝니다. 빌더에는 디코딩된 원래 값을 넣으세요.
- 민감 정보를 쿼리에 넣기: 쿼리스트링은 브라우저 기록, 서버 로그, 리퍼러에 남습니다. 토큰이나 비밀번호는 쿼리 대신 헤더나 본문으로 보내는 것이 일반적인 권장입니다.
- 길이 제한: 브라우저, 프록시, 서버마다 허용 URL 길이가 달라서 수천 자를 넘으면 문제가 생기는 환경이 많습니다. 긴 데이터는 POST 본문으로 보내세요.
- 키 순서와 대소문자: 이 도구는 입력 순서를 유지하며 키의 대소문자를 구분합니다. 서버가 어떻게 취급하는지는 별개입니다.
- URL 전체 검증이 아님: 스킴, 호스트, 포트, 경로의 오류는 검사하지 않습니다. 빌더는 쿼리 부분만 만들며 도메인과 경로는 직접 붙여야 합니다.
- 빈 키 행 무시: 빌더에서 키가 비어 있는 행은 결과에서 제외됩니다. 값만 비어 있으면
key=로 나옵니다.
결과를 활용하는 방법
분해한 값 하나만 인코딩·디코딩해 보고 싶다면 URL 인코더/디코더가 더 간단합니다. 한글 제목에서 경로용 주소를 만드는 경우에는한글 URL 슬러그 생성기가 맞습니다. 쿼리 값에 JSON을 담았다면 디코딩한 값을 JSON 포맷터로 확인하고, Base64로 감싼 값은 Base64 변환기로 풀어 보세요. URL 패턴을 정규식으로 추려 내야 할 때는 정규식 테스터가 도움이 됩니다.
자주 묻는 질문
같은 키에 값이 여러 개면 어떻게 되나요?
쿼리스트링은 같은 키를 여러 번 반복해 값을 여러 개 담을 수 있습니다(예: tag=a&tag=b). 이 도구는 같은 키를 가진 행을 여러 줄로 각각 표시하고 요약에서 중복 키 이름을 알려 줍니다.
URL 전체를 붙여넣지 않고 쿼리스트링만 넣어도 되나요?
네. "?"로 시작하는 쿼리스트링이나 "?" 없이 key=value&key2=value2 형태만 붙여넣어도 인식합니다.
공백이 +로 나오는데 %20이어야 하는 곳에 쓰려면요?
빌더의 "공백을 + 대신 %20으로 인코딩" 옵션을 켜세요. 값에 원래 있던 + 문자는 %2B로 이미 바뀌어 있어 이 옵션이 건드리지 않습니다.
한글이 깨져서(�) 나옵니다.
퍼센트 인코딩된 바이트가 UTF-8이 아니거나(EUC-KR 등 옛 인코딩) 중간에 잘린 경우입니다. 표의 원문 열을 보고 해당 값의 인코딩 방식을 확인하세요. 이 도구는 UTF-8만 디코딩합니다.
프래그먼트(#)는 왜 표시되지 않나요?
프래그먼트는 브라우저 안에서만 쓰이고 서버로 전송되지 않는 영역이라 쿼리스트링에 포함되지 않습니다. 파라미터 분해 전에 제거됩니다.