100% 브라우저 메모리 연산 • 서버 로그 수집 제로 • 즉각적인 실행
Curious Techie개발자 툴박스
ENCODING5분 소요•한국어 Edition100% 브라우저 메모리 실행

URL 인코딩(퍼센트 인코딩)의 원리와 RFC 3986

RFC 3986 표준 규격, 예약된 구분자, UTF-8 바이트 변환 및 쿼리 문자열 처리 가이드.

CT
Curious-Techie Engineering Team검증된 작성자

Web Protocols & Security Architecture Research

발행일:
•
수정일:
•5분 소요
공식 기술 규격:RFC 9110(IETF)
검토자: Curious-Techie Architecture Peer Review Group
핵심 질문 • 즉시 기술 답변

URL 인코딩(퍼센트 인코딩)의 원리와 RFC 3986

TL;DR — 핵심 엔지니어링 요약

  • 퍼센트 인코딩은 비ASCII 및 예약된 URI 문자를 %HH 형식의 16진수 바이트 시퀀스로 변환합니다 (RFC 3986).
  • ?, &, = 등의 예약 문자는 쿼리 파라미터 값 내부에서 반드시 이스케이프되어야 합니다.
  • 자바스크립트에서는 파라미터 값에 encodeURIComponent()를, 전체 URI 경로 보존에는 encodeURI()를 사용합니다.
  • 공백 문자는 RFC 3986 표준에 따라 %20으로, 폼 전송 방식에 따라 +로 인코딩됩니다.
// 기본 개념

핵심 개념 및 아키텍처 구조

Unreserved Characters

Safe

Characters permitted in any URI component without encoding: `ALPHA`, `DIGIT`, `-`, `_`, `.`, `~` (RFC 3986 Section 2.3).

Reserved Characters

Delimiters

Characters with reserved syntactic meaning (e.g. `?` initiates query, `#` initiates fragment, `/` separates path segments).

Percent Triplet (%XX)

Syntax

The 3-character sequence consisting of "%" followed by two hexadecimal digits (0-9, A-F) mapping to a specific byte.

application/x-www-form-urlencoded

Forms

Legacy HTML form encoding MIME type where spaces become `+` instead of `%20`, often handled via URLSearchParams.

UTF-8 Octet Multi-byte Encoding

Unicode

Non-ASCII characters (e.g. accented letters, emojis) are converted into multi-byte UTF-8 sequences, producing multiple percent triplets (e.g. "🚀" -> `%F0%9F%9A%80`).

실행 흐름 • 동작 시퀀스

URL 인코딩(퍼센트 인코딩)의 원리와 RFC 3986의 동작 원리와 메커니즘

핵심 요약 답변:

When a web application parses or constructs a URI, each component (scheme, authority, path, query, fragment) must respect delimiter boundaries. When encoding, the processor converts each character into its UTF-8 byte stream, checks whether each byte is in the unreserved set, and replaces any disallowed byte with `%` plus its uppercase 2-digit hexadecimal representation.

1

String to UTF-8 Byte Stream

Convert characters to raw byte octets according to UTF-8 encoding.

"€" (Euro symbol) -> [0xE2, 0x82, 0xAC]
2

Character Classification

Determine if character is unreserved, reserved-as-data, or reserved-as-delimiter.

"=" used as query value parameter must be encoded; used as key/value delimiter is preserved.
3

Hexadecimal Hex Transformation

Convert each prohibited byte into two hexadecimal characters.

0xE2 -> "E2", 0x82 -> "82", 0xAC -> "AC"
4

Percent Triplet Concatenation

Prefix each byte with "%" to generate the final escaped sequence.

"€" -> "%E2%82%AC"
5

URI Construction

Integrate safe percent triplets into target URI path or query string parameter.

https://api.curious-techie.com/search?currency=%E2%82%AC
기술 예제 • 실전 구현

URL 인코딩(퍼센트 인코딩)의 원리와 RFC 3986의 실무 구현 및 적용 방법

JavaScript: Safe Query Parameter Building using URL and URLSearchParams

typescript
// Constructing robust URLs using modern WHATWG URL API
const baseUrl = "https://api.curious-techie.com/v1/search";
const url = new URL(baseUrl);

// Set query params safely (handles percent encoding automatically!)
url.searchParams.set("q", "cryptographic hashing & signatures");
url.searchParams.set("redirect", "https://app.curious-techie.com/dashboard?view=full");
url.searchParams.set("symbol", "€");

console.log(url.toString());
// Output: https://api.curious-techie.com/v1/search?q=cryptographic+hashing+%26+signatures&redirect=https%3A%2F%2Fapp.curious-techie.com%2Fdashboard%3Fview%3Dfull&symbol=%E2%82%AC

// Reading and decoding params
const params = new URLSearchParams(url.search);
console.log(params.get("q")); // "cryptographic hashing & signatures" (auto decoded)

엔지니어링 상세 정보: Using the WHATWG URL API automatically applies correct percent-encoding to keys and values, avoiding manual concatenation errors.

The Critical Difference: encodeURI vs encodeURIComponent

javascript
const rawParam = "user/profile?role=admin&id=10";

// encodeURI leaves protocol and path delimiters intact:
console.log(encodeURI(rawParam));
// "user/profile?role=admin&id=10" (BROKEN if passed as a query value!)

// encodeURIComponent encodes ALL reserved syntax delimiters:
console.log(encodeURIComponent(rawParam));
// "user%2Fprofile%3Frole%3Dadmin%26id%3D10" (CORRECT for query values)

// Correct usage pattern:
const targetPage = "https://curious-techie.com/auth";
const callback = "https://curious-techie.com/welcome?lang=en";
const fullUrl = `${targetPage}?next=${encodeURIComponent(callback)}`;

엔지니어링 상세 정보: Never pass query parameter values through encodeURI; always use encodeURIComponent to ensure ?, &, and = do not corrupt the outer query structure.

프로덕션 아키텍처 • 실사례 연구

운영 환경에서 URL 인코딩(퍼센트 인코딩)의 원리와 RFC 3986을 사용하는 이유와 구성

OAuth 2.0 & OpenID Connect Authorization Flows

Passing the client callback `redirect_uri` and encrypted `state` tokens in the authorization URL.

Authorization servers require the `redirect_uri` to be strictly percent-encoded to prevent parameter injection attacks.

Search Engine Deep Links and Unicode Tags

Generating clean canonical URLs for technical tags containing symbols like C++, C#, or international language characters.

Paths like `/tags/c%2B%2B` preserve the plus symbol without being stripped or treated as whitespace by web servers.

안티패턴 및 주의사항

URL 인코딩(퍼센트 인코딩)의 원리와 RFC 3986 구현 시 자주 발생하는 실수와 오해

안티패턴: Using `encodeURI()` on individual query parameter values

영향도: Reserved delimiters like `&` and `=` in the value remain unencoded, corrupting the query string into unexpected split parameters.

권장 해결책: Always use `encodeURIComponent()` or `URLSearchParams` for parameter values.

안티패턴: Double Encoding URLs (%2520 bug)

영향도: Encoding an already-encoded URL transforms `%20` into `%2520`, resulting in literal `%20` text appearing on the screen instead of spaces.

권장 해결책: Only encode raw, unencoded input values once; never pass an assembled URL back through encoding functions.

안티패턴: Confusing `+` and `%20` across HTTP specs

영향도: Using `+` inside URI path segments represents a literal plus character, but in `application/x-www-form-urlencoded` query strings it represents a space.

권장 해결책: Follow RFC 3986 strictly: use `%20` for paths; rely on standard URL parsers for form-encoded queries.

위협 모델링 • 공격 벡터

URL 인코딩(퍼센트 인코딩)의 원리와 RFC 3986의 보안 영향 및 취약점 분석

Path Traversal via Nested Percent-Encoding

CWE-22 Improper Limitation of a Pathname to a Restricted Directory

취약점: WAF or proxy decodes `%2e%2e%2f` once to `../`, or decodes `%252e%252e%252f` to bypass path restriction filters.

완화 및 방어 전략: Normalize and validate paths AFTER all URL decoding has completed; verify paths resolve within root directory boundaries.

Server-Side Request Forgery (SSRF) via Encoded Delimiters

OWASP Top 10 A10:2021 Server-Side Request Forgery (SSRF)

취약점: Attacker passes percent-encoded credentials or newline injections (`%0d%0a`) into backend HTTP client URLs.

완화 및 방어 전략: Use strict URL parser objects rather than string interpolation; validate hostnames against an IP allowlist.
진단 워크플로 • 근본 원인 해결

URL 인코딩(퍼센트 인코딩)의 원리와 RFC 3986 오류 진단 및 트러블슈팅 가이드

발생 증상 및 오류 징후: Plus signs "+" in query strings are unexpectedly replaced with empty spaces on the server

근본 원인 기술 분석:
  • Server parser defaults to application/x-www-form-urlencoded specification where "+" signifies space
프로덕션 검증 해결책: Percent-encode literal plus signs as `%2B` in query string parameter values.

발생 증상 및 오류 징후: URIError: URI malformed during `decodeURIComponent()`

근본 원인 기술 분석:
  • Input string contains an incomplete percent sequence (e.g. "item%2" or "%FF" invalid UTF-8 sequence)
프로덕션 검증 해결책: Wrap decoding in a `try...catch` block or validate percent triplets match `/%[0-9a-fA-F]{2}/g`.
기술 지식베이스 • 즉시 답변

URL 인코딩(퍼센트 인코딩)의 원리와 RFC 3986에 대한 자주 묻는 질문

Q:What is the difference between URL encoding and percent-encoding?

핵심 요약 답변:There is no difference; percent-encoding is the formal technical term defined in RFC 3986, while "URL encoding" is the colloquial industry name for the same mechanism.

Both terms refer to replacing non-ASCII or reserved characters with a percent symbol "%" followed by two hexadecimal digits representing the byte in UTF-8.

Q:Should a space be encoded as "+" or "%20"?

핵심 요약 답변:In standard RFC 3986 URI paths and headers, space must always be encoded as "%20". In query strings submitted via HTML forms (application/x-www-form-urlencoded), "+" is permitted as an alias for space.

Modern REST APIs and WHATWG specifications prefer "%20" consistently across both paths and queries to prevent ambiguity.

섹션 12 • 대화형 실습 유틸리티

추천 관련 개발자 도구

100% 브라우저 메모리 실행

Companion Interactive Tool100% Client-Side Execution

Test & Verify with URL Encoder / Decoder

Encode and decode URL parameters and query strings (RFC 3986).

Companion Interactive Tool100% Client-Side Execution

Test & Verify with Base64 Encoder / Decoder

Encode and decode Base64 strings and UTF-8 text client-side.

Companion Interactive Tool100% Client-Side Execution

Test & Verify with Hex ↔ Text Converter

Convert plain text to hexadecimal bytes and hex strings back to text.

Companion Interactive Tool100% Client-Side Execution

Test & Verify with HTTP Header Analyzer

Analyze raw or live HTTP response headers for caching and architecture.

용어사전

Percent-Encoding
A mechanism to encode arbitrary data in a URI using only US-ASCII characters.
Reserved Characters
Characters that have special structural meaning within a URI, such as "/", "?", "&", and "#".
Unreserved Characters
Characters that are allowed in any URI without being percent-encoded (A-Z, a-z, 0-9, "-", "_", ".", "~").