跳到主要内容

3. WebSocket URI

本规范使用 RFC 3986 中的 ABNF 语法和术语定义了两个 URI scheme.

URI Scheme 定义

ws-URI (未加密)

ws-URI = "ws:" "//" host [ ":" port ] path [ "?" query ]
  • Scheme name: ws
  • Default port: 80
  • Purpose: 未加密的 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 ]
  • Scheme name: wss
  • Default port: 443
  • Purpose: TLS 加密的 WebSocket 连接

示例:

wss://example.com/socket
wss://secure.example.com:8443/chat

URI 组成部分说明

host

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:// 的优势:

  • 加密传输, 防止中间人攻击
  • 防止数据被窃听
  • 更好地穿越防火墙
  • 支持浏览器安全策略 (例如 mixed content policy)

ws:// 的风险:

  • 数据以明文传输
  • 容易被截获和篡改
  • 浏览器可能会阻止 HTTPS 页面发起 ws:// 连接

Origin 验证

服务器应验证 Origin header, 确保连接只来自受信任的来源:

// Server-side validation example
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 客户端

// Connect to unencrypted WebSocket
const ws1 = new WebSocket('ws://example.com/socket');

// Connect to TLS encrypted WebSocket (recommended)
const ws2 = new WebSocket('wss://example.com/socket');

// With port and path
const ws3 = new WebSocket('wss://example.com:8443/chat/room1');

// With query parameters
const ws4 = new WebSocket('wss://example.com/socket?token=abc123');

相关规范

  • RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
  • RFC 2818: HTTP Over TLS

参考链接