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,不显式释放,连接资源就一直占着:
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
- 错误写法:
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 存在,三者缺一不可。少验一个,就卡在“连不上”却查不出原因。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










