URL/URI Anatomy, Dissected

The components scheme, authority (userinfo/host/port), path, query, and fragment; percent-encoding; reserved vs unreserved characters; IDN/punycode; relative vs absolute; and normalization.

A URL is the address of a web resource, but it's really a structure of well-defined parts assembled in a fixed order. Its grammar is set by RFC 3986, and understanding it precisely clarifies most routing, encoding, and security issues. First, the terms: a URI is the broader concept that identifies a resource, and a URL is the kind that also tells you its location. In everyday use the two are treated as synonyms.

The five components

RFC 3986's generic syntax is scheme://authority/path?query#fragment. Let's map each part onto an example.

https://user:pass@api.example.com:8443/v1/items?sort=asc&page=2#section-3
\___/   \_______/ \_____________/ \__/ \_______/ \_____________/ \_______/
scheme  userinfo      host        port    path        query       fragment
              \__________________________/
                     authority

Percent-encoding and character sets

You can't put arbitrary characters in a URL. RFC 3986 splits characters into two groups. Unreserved characters (A-Z a-z 0-9 - . _ ~) may appear literally anywhere. Reserved characters (: / ? # [ ] @ ! $ & ' ( ) * + , ; =) carry special meaning as delimiters, so to include one as data you must percent-encode it. A space becomes %20, & becomes %26, and the Korean syllable '한' becomes %ED%95%9C (its UTF-8 bytes encoded).

The key point is that encoding rules depend on context. The same / is left alone as a path separator, but to place it as data inside a query value you must encode it as %2F. That's why browsers and standard libraries provide separate encoders for 'a path segment' versus 'a query component.' Using the wrong one causes bugs where + (which can mean a space in a query) or / is misinterpreted.

IDN and punycode

Using non-ASCII characters (Korean, Chinese, emoji, etc.) in a domain is an Internationalized Domain Name (IDN). Since DNS traditionally handles only ASCII, a Unicode domain is converted to an ASCII form via punycode, and the converted label gets an xn-- prefix. For example, the Korean label of 한국.example encodes to something like xn--3e0b707e. Because of homograph attacks — mixing visually similar characters to forge a domain — browsers sometimes show punycode instead of Unicode in the address bar.

Relative vs absolute, and normalization

An absolute URL is a complete address with a scheme and everything, while a relative URL (../images/logo.png, ?page=2) is interpreted against the current document's base URL. Browsers resolve relative to absolute using RFC 3986's reference-resolution rules.