URL 인코딩이란 무엇이고 왜 필요한가?
퍼센트 인코딩이라고도 알려진 URL 인코딩은 URL에서 정보를 인코딩하는 기본 메커니즘입니다. 웹 주소에서 %20이나 %3F를 본 적이 있다면 URL 인코딩을 실제로 경험한 것입니다.
URL 인코딩이 존재하는 이유
URL(Uniform Resource Locator)은 인터넷 초기에 엄격한 제한사항과 함께 설계되었습니다. URL에는 ASCII 문자 세트에서 특정 문자 집합만 포함될 수 있습니다:
- 문자:
A-Z,a-z - 숫자:
0-9 - 안전한 문자:
-,_,.,~
하지만 문제가 있습니다: 웹 애플리케이션은 공백, 특수 기호, 모든 인간 언어의 문자를 포함한 모든 종류의 데이터를 URL을 통해 전송해야 합니다. URL 인코딩이 이 문제를 해결합니다.
URL 인코딩이 해결하는 문제
예약 문자는 특별한 의미를 가짐
URL의 특정 문자에는 특정 목적이 있습니다:
| 문자 | 목적 | 예시 |
|---|---|---|
? | 쿼리 문자열 시작 | example.com/search?q=test |
& | 파라미터 구분 | ?name=John&age=25 |
= | 파라미터에 값 할당 | ?key=value |
# | 프래그먼트 표시 | example.com/page#section |
/ | 경로 세그먼트 구분 | example.com/blog/post |
: | 프로토콜/포트 구분 | https://example.com:8080 |
인코딩 없이는 어떻게 될까요?
"Tom & Jerry"를 검색하고 싶다고 가정해봅시다:
❌ 잘못됨: example.com/search?q=Tom & Jerry
브라우저는 &를 파라미터 구분자로 해석하여 두 개의 파라미터가 됩니다:
q=Tom(불완전!)Jerry(이게 뭐지?)
인코딩 사용:
✅ 올바름: example.com/search?q=Tom%20%26%20Jerry
이제 명확합니다: 하나의 파라미터 q에 값은 "Tom & Jerry"입니다.
국제 문자는 ASCII가 아님
원래 ASCII 문자 세트에는 다음이 포함되지 않습니다:
- 중국어 문자: 中文
- 아랍 문자: العربية
- 이모지: 😀
- 악센트 문자: café, naïve
URL 인코딩으로 이 모든 문자를 전송 가능하게 만듭니다.
URL 인코딩의 작동 방식
인코딩 프로세스는 간단한 규칙을 따릅니다:
특수 문자를 %와 그 뒤에 문자 값을 나타내는 두 자리 16진수로 대체합니다.
일반적인 문자 인코딩
| 문자 | 이름 | 인코딩됨 | 인코딩되는 이유 |
|---|---|---|---|
| 공백 | %20 | 공백은 허용되지 않음 |
! | 느낌표 | %21 | 일부 시스템과 충돌할 수 있음 |
# | 해시 | %23 | URL 프래그먼트 표시 |
$ | 달러 | %24 | 향후 사용을 위해 예약됨 |
% | 퍼센트 | %25 | 인코딩 표시자 자체! |
& | 앰퍼샌드 | %26 | 파라미터 구분자 |
+ | 플러스 | %2B | 일부 컨텍스트에서 공백을 의미할 수 있음 |
= | 등호 | %3D | 키-값 구분자 |
? | 물음표 | %3F | 쿼리 문자열 시작 |
@ | 골뱅이 | %40 | 사용자 정보 구분자 |
16진수 작동 방식
각 문자에는 ASCII 코드가 있습니다. 16진수(base-16) 표현은 인코딩을 간결하게 만듭니다:
공백 문자:
- ASCII 코드: 32(10진수)
- 16진수: 20
- 인코딩됨: %20
앰퍼샌드 (&):
- ASCII 코드: 38(10진수)
- 16진수: 26
- 인코딩됨: %26
UTF-8과 국제 문자
ASCII 외의 문자(기본적으로 영어가 아닌 모든 것)의 경우, URL 인코딩은 UTF-8을 사용합니다:
- 문자를 UTF-8 바이트로 변환
- 각 바이트를
%XX로 인코딩
예시
중국어 문자 "中":
문자: 中
UTF-8 바이트: E4 B8 AD (3 바이트)
인코딩됨: %E4%B8%AD
이모지 "😀":
문자: 😀
UTF-8 바이트: F0 9F 98 80 (4 바이트)
인코딩됨: %F0%9F%98%80
이로써 모든 언어의 모든 문자가 URL을 통해 전송 가능해집니다!
실제 사용 사례
1. 검색 쿼리
Google에서 무언가를 검색할 때:
입력 내용: "best coffee in tokyo"
URL 내용: ?q=best%20coffee%20in%20tokyo
2. 폼 제출
method="GET"인 HTML 폼은 폼 데이터를 인코딩합니다:
<form method="GET" action="/search">
<input name="product" value="women's shoes" />
<input name="size" value="7" />
</form>
제출처: /search?product=women%27s%20shoes&size=7
3. API 요청
파라미터가 있는 RESTful API 호출 구축:
원본: /api/users?name=John Doe&[email protected]
인코딩됨: /api/users?name=John%20Doe&email=john%40example.com
4. 인증
OAuth 리디렉션 URL에는 종종 인코딩된 콜백 URL이 포함됩니다:
/oauth/authorize?redirect_uri=https%3A%2F%2Fmyapp.com%2Fcallback
5. 공유 링크
소셜 미디어 공유 버튼은 공유되는 URL을 인코딩합니다:
https://twitter.com/intent/tweet?url=https%3A%2F%2Fexample.com%2Farticle&text=Check%20this%20out%21
언제 인코딩하는가
항상 인코딩:
✅ 쿼리 파라미터의 사용자 입력 ✅ 특수 문자가 있는 폼 데이터 ✅ 국제 텍스트(중국어, 아랍어, 이모지 등) ✅ 공백이 있는 파일 경로 ✅ URL의 이메일 주소 ✅ URL의 JSON 데이터
보통 인코딩할 필요 없음:
❌ 경로 자체(특수 문자가 없는 한)
❌ 도메인 이름
❌ 프로토콜(https://)
❌ 제어 가능한 표준 구두점
URL 인코딩 방법
JavaScript
// 파라미터 값용(가장 일반적)
const query = "hello world!";
const encoded = encodeURIComponent(query);
// 결과: "hello%20world%21"
// 전체 URL용
const url = "https://example.com/search?q=hello world";
const encoded = encodeURI(url);
// 결과: "https://example.com/search?q=hello%20world"
Python
from urllib.parse import quote, quote_plus
# 표준 인코딩
text = "hello world!"
encoded = quote(text) # 'hello%20world%21'
# 플러스 인코딩(폼 데이터용)
encoded = quote_plus(text) # 'hello+world%21'
PHP
// 파라미터 값용
$query = "hello world!";
$encoded = urlencode($query); // "hello+world%21"
// 일반 용도
$encoded = rawurlencode($query); // "hello%20world%21"
일반적인 함정
1. 사용자 입력 인코딩 잊어버리기
// ❌ 위험 - 특수 문자로 손상됨
const url = `/search?q=${userInput}`;
// ✅ 안전 - 항상 인코딩
const url = `/search?q=${encodeURIComponent(userInput)}`;
2. 이중 인코딩
// ❌ 잘못됨 - 두 번 인코딩
const text = "hello world";
const encoded = encodeURIComponent(encodeURIComponent(text));
// 결과: "hello%2520world" (손상됨!)
// ✅ 올바름 - 한 번 인코딩
const encoded = encodeURIComponent(text);
// 결과: "hello%20world"
3. 전송 후 디코딩하지 않기
// ❌ 잘못됨 - 인코딩된 텍스트를 사용자에게 표시
console.log(params.get('name')); // "John%20Doe"
// ✅ 올바름 - 표시용으로 디코딩
console.log(decodeURIComponent(params.get('name'))); // "John Doe"
모범 사례
- 사용자 입력은 항상 인코딩 - URL에 넣기 전에
- 내장 함수 사용 - 수동으로 인코딩하려 하지 마세요
- 올바른 함수 선택 - 파라미터에는
encodeURIComponent() - 읽을 때 디코딩 - 사용자에게
%20을 표시하지 마세요 - 특수 문자로 테스트 - 공백,
&,=,#포함 - 국제 텍스트로 테스트 - 중국어, 아랍어, 이모지
- URL에 민감한 데이터를 넣지 마세요 - 인코딩되어도 보임
URL 테스트하기
URL 인코딩을 시험해보고 싶으신가요? 이 무료 도구들을 사용해보세요:
결론
URL 인코딩은 웹 개발을 위한 간단하지만 필수적인 개념입니다. 이것은 다음을 보장합니다:
- 특수 문자가 URL을 손상시키지 않음
- 국제 텍스트를 전송할 수 있음
- 데이터가 클라이언트와 서버 간에 안전하게 흐름
- URL이 모든 시스템에서 일관되게 작동함
기억하세요: 의심스러울 때는 인코딩하세요! URL(그리고 사용자)이 감사할 것입니다.
무료 URL 인코더를 사용하여 URL을 즉시 인코딩하거나, URL 디코더를 사용하여 퍼센트 인코딩된 문자열을 디코딩하세요!