WebTransport不是WebSocket平替,它基于HTTP/3(QUIC),仅支持HTTPS或localhost,需浏览器与服务端均真实启用h3协议;验证须检查DevTools Network面板Protocol列为h3、curl --http3响应成功,并确保new WebTransport()地址合法;datagram用于不可靠低延迟场景,stream用于可靠有序传输,二者语义不同且需显式关闭流资源;Node.js原生不支持QUIC,推荐Caddy或nginx-quic部署。

WebTransport 不是 WebSocket 的平替,它依赖 HTTP/3(QUIC),必须在 https:// 或 http://localhost 下运行,且浏览器和服务端都得真正在用 h3 协议。直接把 WebSocket 地址换成 WebTransport 构造函数参数,90% 会立刻报错或静默失败。
如何确认 WebTransport 真的能用
别信文档说“Chrome 115+ 支持”,要验证实际协商结果:
- 打开 Chrome DevTools → Network 面板 → 刷新页面 → 找任意一个请求 → 看 Protocol 列是不是
h3;如果是h2或http/1.1,navigator.webtransport就是undefined - 终端执行:
curl -I --http3 https://your-domain.com,看是否返回HTTP/3响应头;没响应或报错,说明服务端 QUIC 没开 -
new WebTransport('http://example.com')会直接抛SecurityError;非 localhost 的纯 HTTP 不被允许
datagram 和 stream 的选择逻辑
不是“哪个更高级”,而是语义完全不同:
-
transport.datagrams:不可靠、无序、无重传,类似加密 UDP,适合心跳、游戏状态同步、丢得起的小包 —— 这才是低延迟的关键入口 -
transport.createBidirectionalStream():可靠、有序、流控,类似 TCP,适合指令、配置同步、小文件传输;但单一流阻塞不影响其他流,这是比 WebSocket 强的地方 - 别用
stream传大视频帧;应该拆成多个流分优先级,或改用datagram+ 应用层 FEC
流不 close 就泄漏,不是警告是事实
createBidirectionalStream() 返回的流绑定 QUIC 连接中的独立流 ID,不显式释放,连接资源就一直占着:
把任意文章或文档内容转换成精美的全屏翻页 HTML 演示文件(幻灯片风格)。当用户发来一篇文章、文档链接、Markdown 内容、或粘贴的文本,并且希望生成演示用的 HTML 时触发。支持任意内容来源:iWiki 链接、KM 链接、本地文件路径、直接粘贴的文本。生成的 HTML 文件保存到本地工作区,并通过企微直接发送给用户。触发词示例:帮我把这篇文章做成PPT、转成演示文档、生成HTML幻灯片、做个演示、转成可以演示的格式、article to deck、make a slide。
- 错误写法:
await writer.write(encoder.encode("ping"))后啥也不做 —— 流没关,writer 没 abort,reader 没 release - 正确做法:写完后调
await writer.close()(正常结束)或await writer.abort()(出错中断);reader 侧也要在done后reader.releaseLock() - 漏掉
releaseLock()可能导致后续getReader()报InvalidStateError
服务端必须支持 QUIC,Node.js 原生不行
Node.js 标准 https.Server 不支持 HTTP/3;目前没有稳定、生产可用的原生 QUIC 模块:
立即学习“前端免费学习笔记(深入)”;
- 推荐方案:用 Caddy(v2.8+ 默认启
h3),配protocols h1 h2 h3;或 nginx-quic 分支(需自己编译) - Cloudflare 提供的
@cloudflare/webtransport是封装层,底层仍需真实 QUIC 服务器配合,不能 standalone 运行 - 本地开发可跑
https://localhost:8080+ Caddy,但部署到 Nginx without QUIC 模块的服务器上,WebTransport必然 fallback 失败
WebTransport 的坑不在 API 写法,而在协议栈协同——浏览器显示 h3,服务端日志打出 QUIC handshake 成功,客户端 navigator.webtransport 存在,三者缺一不可。少验一个,就卡在“连不上”却查不出原因。

















