跳到主要内容

3. 语法组件 (Syntax Components)

通用 URI 语法由一组层次化组件组成, 分别称为方案 (scheme), 授权 (authority), 路径 (path), 查询 (query) 和片段 (fragment).

URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]

hier-part = "//" authority path-abempty
/ path-absolute
/ path-rootless
/ path-empty

组件结构示例:

  foo://example.com:8042/over/there?name=ferret#nose
\_/ \______________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment
| _____________________|__
/ \ / \
urn:example:animal:ferret:nose

以下各节详细描述每个组件.


3.1. 方案 (Scheme)

每个 URI 都以方案名称开始, 方案名称指向用于在该方案内分配标识符的规范. 方案名称由一串字符组成, 以字母开头, 后面跟随字母, 数字, 加号 ("+"), 句点 (".") 或连字符 ("-") 的任意组合.

scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )

示例:

  • http
  • https
  • ftp
  • mailto
  • file
  • data
  • tel

方案名称不区分大小写. 规范形式为小写, 规范化器应当将方案名称转换为小写.

注: 虽然方案不区分大小写, 生成者和规范化器仍应使用小写字母.


3.2. 授权 (Authority)

授权组件由可选的用户信息子组件, 主机子组件和可选的端口子组件组成, 并以前导的两个斜杠 ("//") 引入.

authority = [ userinfo "@" ] host [ ":" port ]

完整示例:

user:[email protected]:8080
\__________/ \______________/ \__/
userinfo host port

3.2.1. 用户信息 (User Information)

userinfo 子组件可以由用户名组成, 也可以可选地包含特定于方案的信息, 用于说明如何获得访问资源的授权.

userinfo = *( unreserved / pct-encoded / sub-delims / ":" )

示例:

  • user@host
  • user:password@host (已弃用, 存在安全风险)
  • anonymous@host

安全警告: 在 URI 中包含密码已被弃用, 因为密码可能暴露在日志, 历史记录等位置.


3.2.2. 主机 (Host)

host 子组件可以是注册名称 (包括但不限于主机名), 也可以是 IP 地址. IPv6 地址必须括在方括号中.

host = IP-literal / IPv4address / reg-name

IP-literal = "[" ( IPv6address / IPvFuture ) "]"

IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet

reg-name = *( unreserved / pct-encoded / sub-delims )

主机类型示例:

1. 注册名称

www.example.com
example.org
localhost

2. IPv4 地址

192.0.2.1
127.0.0.1

3. IPv6 地址

[2001:db8::1]
[::1]
[fe80::1]

4. 未来 IP 版本

[v9.abc:def]

主机规范化: 主机名不区分大小写, 应当规范化为小写.


3.2.3. 端口 (Port)

port 子组件是可选的, 并以十进制数字表示.

port = *DIGIT

示例:

  • http://example.com:80/ (HTTP 默认端口)
  • https://example.com:443/ (HTTPS 默认端口)
  • http://example.com:8080/ (自定义端口)

默认端口: 如果端口为空或未给出, 则假定使用该方案的默认端口.


3.3. 路径 (Path)

path 组件包含用于在 URI 方案和命名授权范围内标识资源的数据, 并与 query 组件中的数据共同发挥作用. 路径由斜杠 ("/") 字符分隔的一系列路径段组成.

path          = path-abempty    ; begins with "/" or is empty
/ path-absolute ; begins with "/" but not "//"
/ path-noscheme ; begins with a non-colon segment
/ path-rootless ; begins with a segment
/ path-empty ; zero characters

path-abempty = *( "/" segment )
path-absolute = "/" [ segment-nz *( "/" segment ) ]
path-noscheme = segment-nz-nc *( "/" segment )
path-rootless = segment-nz *( "/" segment )
path-empty = 0<pchar>

segment = *pchar
segment-nz = 1*pchar
segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )

pchar = unreserved / pct-encoded / sub-delims / ":" / "@"

路径类型示例:

1. 绝对路径

/path/to/resource
/index.html
/

2. 相对路径

path/to/resource
../parent/resource
resource

3. 空路径

http://example.com

路径段: 路径由斜杠分隔的段组成. 特殊段包括:

  • . (当前目录)
  • .. (父目录)

3.4. 查询 (Query)

query 组件包含非层次化数据, 并与 path 组件中的数据共同用于标识资源. query 组件由问号 ("?") 引入.

query = *( pchar / "/" / "?" )

查询字符串示例:

?key=value
?name=John&age=30
?search=hello+world
?filter[]=a&filter[]=b
?q=%E4%BD%A0%E5%A5%BD

常见格式: 虽然 URI 规范没有定义查询字符串格式, 但以 & 分隔的 key=value 对已经成为事实标准:

?key1=value1&key2=value2&key3=value3

3.5. 片段 (Fragment)

fragment 组件允许间接标识由 URI 所标识资源的表示中的次级资源. 片段标识符由井号 ("#") 引入.

fragment = *( pchar / "/" / "?" )

片段示例:

#section1
#top
#chapter-3
#line-42

重要特性:

  1. 客户端处理: 片段标识符由客户端处理, 不会发送到服务器.
  2. 文档内导航: 常用于 HTML 文档中的锚点.
  3. 次级资源: 标识主资源的一部分.

示例:

http://example.com/page.html#section2
  • 服务器接收: http://example.com/page.html
  • 客户端导航到: #section2

URI 组件摘要

组件前缀必需示例描述
scheme-http协议/方案
authority//user@host:port授权信息
path-是*/path/to/resource资源路径
query?key=value查询参数
fragment#section1片段标识符

*路径可以为空.


完整 URI 示例拆解

示例 1: HTTP URL

https://user:[email protected]:8080/path/to/page?key=value#section
组件
schemehttps
userinfouser:pass
hostwww.example.com
port8080
path/path/to/page
querykey=value
fragmentsection

示例 2: Mailto URI

mailto:[email protected]?subject=Hello
组件
schememailto
path[email protected]
querysubject=Hello

示例 3: File URI

file:///home/user/document.txt
组件
schemefile
authority(空)
path/home/user/document.txt

组件编码规则

不同组件允许不同的字符集:

组件允许的特殊字符必须编码的字符
scheme+ - .其他所有字符
userinfo: ! $ & ' ( ) * + , ; =其他所有字符
host- . _ (reg-name)其他所有字符
port0-9其他所有字符
path: @ ! $ & ' ( ) * + , ; =其他所有字符
query: @ / ? ! $ & ' ( ) * + , ; =其他所有字符
fragment: @ / ? ! $ & ' ( ) * + , ; =其他所有字符

下一章: 4. URI 引用 (URI Reference) - URI 引用和相对引用