不要逐块解析 JSON

浏览器从网络读取到的 Uint8Array 分块,边界不保证和服务端的事件或 JSON 对象边界一致。一个 JSON 字符串可能在反斜杠、引号甚至 UTF-8 多字节字符中间被拆开。先用增量文本解码器保留跨块字节,再按所用协议累计完整事件,最后解析事件数据。

网络块 A: data: {"delta":"你
网络块 B: 好"}\n\n
完整事件: data: {"delta":"你好"}\n\n

上面只是说明分块现象的示例,不代表所有供应商都使用相同字段。采用 SSE 时,事件一般以空行分隔;有些服务使用命名事件和不同的完成标记。请以具体 API 文档为准。

区分三种结束

  1. 正常完成:收到服务定义的完成事件,保存完整输出和 usage。
  2. 用户取消:主动中止请求,界面标注“已停止”,不要把部分文本当作成功结果。
  3. 网络或服务错误:保留已经收到的片段供查看,但状态应为“未完成”;可提示重新生成或继续请求。

怎么复现

在测试环境让服务端发送两段数据,并故意在第二段之后断开。前端应显示“未完成”,而不是“生成成功”。再测试中文字符恰好跨网络分块、末尾没有空行、收到错误事件这三种边界。记录事件序列与请求标识,别把用户原文写进公开日志。

如果最终结果必须满足 JSON Schema,不要在流式中间就当作完整对象提交给业务系统;等完成信号并通过完整解析和字段校验后再使用。

参考:WHATWG Server-Sent Events 规范、MDN SSE 指南。