3. WebSocket URIs
本规范定义了两个URI方案,使用ABNF语法和RFC 3986中定义的术语。
URI方案定义
ws-URI (非加密)
ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ]
- 方案名称: ws
- 默认端口: 80
- 用途: 非加密WebSocket连接
示例:
ws://example.com/socket
ws://example.com:8080/chat
ws://192.168.1.1/data
wss-URI (TLS加密)
wss-URI = "wss:" "//" host [ ":" port ] path [ "?" query ]
- 方案名称: wss
- 默认端口: 443
- 用途: TLS加密的WebSocket连接
示例:
wss://example.com/socket
wss://secure.example.com:8443/chat
URI组件说明
host (主机)
主机部分可以是:
- 域名:
example.com - IPv4地址:
192.168.1.1 - IPv6地址:
[2001:db8::1]
port (端口)
- 如果省略,使用默认端口(ws为80,wss为443)
- 可以显式指定任何有效端口
path (路径)
- 必须以
/开头 - 如果为空,则默认为
/
query (查询字符串)
- 可选的查询参数
- 格式:
?key1=value1&key2=value2
安全考虑
推荐使用wss://
在生产环境中,强烈推荐使用wss://(TLS加密)而不是ws://:
✅ 使用wss://的优势:
- 加密传输,防止中间人攻击
- 防止数据被窃听
- 更好的防火墙穿透能力
- 浏览器安全策略的支持(如混合内容策略)
❌ ws://的风险:
- 数据明文传输
- 容易被拦截和篡改
- 浏览器可能阻止从HTTPS页面连接到ws://
原点验证
服务器应该验证Origin头部,确保只接受来自可信来源的连接:
// 服务器端验证示例
const allowedOrigins = ['https://example.com', 'https://app.example.com'];
const origin = request.headers['origin'];
if (!allowedOrigins.includes(origin)) {
response.status(403).send('Forbidden');
}
URI解析示例
示例1: 完整URI
wss://chat.example.com:8443/room/general?user=alice
解析结果:
- Scheme: wss
- Host: chat.example.com
- Port: 8443
- Path: /room/general
- Query: user=alice
示例2: 最小URI
ws://example.com
解析结果:
- Scheme: ws
- Host: example.com
- Port: 80 (默认)
- Path: / (默认)
- Query: (无)
示例3: IPv6地址
wss://[2001:db8::1]:443/socket
解析结果:
- Scheme: wss
- Host: 2001:db8::1
- Port: 443
- Path: /socket
浏览器使用示例
JavaScript客户端
// 连接到非加密WebSocket
const ws1 = new WebSocket('ws://example.com/socket');
// 连接到TLS加密WebSocket (推荐)
const ws2 = new WebSocket('wss://example.com/socket');
// 带端口和路径
const ws3 = new WebSocket('wss://example.com:8443/chat/room1');
// 带查询参数
const ws4 = new WebSocket('wss://example.com/socket?token=abc123');
相关规范
- RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
- RFC 2818: HTTP Over TLS
参考链接
- 上一章: 2. Conformance Requirements
- 下一章: 4. Opening Handshake
- 实现指南: WebSocket URI详解