HTTP/1.1同源并发限制为6个,导致SSE或fetch流式请求在同域名下超过6个时全部pending;通过Network面板查看protocol为http/1.1且domain一致的pending请求即可确诊。

直接看网络面板里的请求状态和协议版本,是识别 HTTP/1.1 同源连接数限制导致流式窗口死锁最有效的方式。核心线索是:多个 SSE 或 fetch + ReadableStream 请求长时间处于 pending 状态,且全部来自同一域名(含协议、端口),同时协议显示为 http/1.1。
观察 Network 面板中的关键信号
打开浏览器开发者工具 → Network 标签页,刷新页面后关注流式请求(如 /events、/stream、或带 text/event-stream 响应头的请求):
- 筛选出所有 status 为 (pending) 的请求,检查它们的 Domain 列是否完全一致(例如都是
https://api.example.com:8080) - 在 Protocol 列确认这些 pending 请求是否都标记为 http/1.1(Chrome/Edge/Firefox 均支持该列显示)
- 查看已成功发起的同域请求总数 —— 若恰好卡在 6 个活跃连接(比如 5 个已完成 + 1 个 pending),而第 7 个及之后全部 pending,基本可锁定为并发限制
- 注意:SSE 连接一旦建立即长期保持,不会自动释放,因此 6 个 slot 很容易被占满且不释放
验证是否存在“连接占满未释放”现象
HTTP/1.1 下,SSE 是长连接,浏览器不会主动关闭,容易形成“伪死锁”——前端以为能开新流,实际已被堵死:
- 在控制台执行
performance.getEntriesByType('resource').filter(r => r.name.includes('your-stream-path')).length,统计当前页面已发起的流请求数 - 手动触发一次新流(如调用
new EventSource(...)),再刷新 Network 面板,观察它是否始终 pending,且没有触发onopen或onerror - 尝试关闭一个已有 SSE 连接(
es.close()),等待 2–3 秒后立即发起新连接 —— 若新连接立刻进入 pending 并很快变为 active,说明旧连接释放后 slot 恢复,进一步佐证限制存在
排除其他干扰因素
避免误判为服务端问题或代码逻辑错误,需快速交叉验证:
- 换用 不同子域名(如把
api.example.com改成stream.example.com)重试,若新域名下能同时跑满 6 个流且无阻塞,说明是同源隔离机制生效 - 临时将后端服务升级为 HTTP/2(需 HTTPS + TLS 1.2+,并确保服务器启用 ALPN 协商),同一域名下发起 10+ 个 SSE,观察是否全部并行建立成功
- 禁用浏览器缓存与扩展(尤其是广告拦截类),防止插件劫持或中断连接
- 使用 curl 模拟单个 SSE 请求:
curl -N https://api.example.com/events,确认服务端本身能正常响应流式数据,排除后端挂起或超时
快速定位是否为开发环境特有
本地开发常因使用 localhost 或自签名证书触发额外限制:
- Chrome 对
localhost的同源限制与正式域名一致(仍是 6 个),但某些代理工具(如 vite dev server)默认不启用 HTTP/2,易被忽略 - 若使用
https://localhost:3000且证书不受信,浏览器可能降级回 HTTP/1.1,即使服务端支持 h2 - 建议在本地用真实二级域名(如
dev.example.test+ mkcert 生成可信证书)复现,更贴近生产行为

















