You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter SSE客户端处理大响应时报FormatException: Unterminated string如何解决

问题根本原因
  • 分片截断导致UTF8解码失败:http请求返回的流式响应是按字节分片传输的,分片边界完全由网络层决定,不保证对应完整的UTF8字符。当响应体积较大时,很容易出现某个分片末尾刚好截断了一个多字节UTF8字符的情况,此时直接调用utf8.decode(d)就会抛出Unterminated string格式异常。
  • SSE事件解析逻辑不符合流规范:现有逻辑每拿到一个分片就直接按换行拆分、硬取下标为1的元素作为事件内容,完全没有考虑单条SSE事件可能会跨多个分片传输的场景。大体积的SSE事件必然会被拆到多个分片中,直接解析单个分片只能拿到不完整的事件内容,不仅会触发解析错误,还会导致业务数据丢失。
修复方案

你需要新增字节缓冲区逻辑,先攒够完整的SSE事件再做解析,核心修改逻辑如下:

  1. 初始化一个字节缓存区,每次接收到新的分片字节,先全部追加到缓存区中
  2. 从缓存区中拆分出所有完整的SSE行(行分隔符支持\n/\r\n/\r),拆分后剩余的不完整字节留在缓存区等待后续分片拼接
  3. 按SSE协议规范逐行解析事件字段,遇到空行时判定当前事件已经接收完整,再将完整事件数据传入SSEModel.fromData处理

修复后的核心代码示例

while (true) {
  try {
    _client = http.Client();
    var request = http.Request("GET", Uri.parse(url));
    request.headers["Cache-Control"] = "no-cache";
    request.headers["Accept"] = "text/event-stream";
    request.headers["Cookie"] = token;
    var response = await _client.send(request);
    // 新增字节缓冲区
    List<int> buffer = [];
    await for (final chunk in response.stream) {
      buffer.addAll(chunk);
      // 拆分完整行
      int lineStart = 0;
      for (int i = 0; i < buffer.length; i++) {
        // 匹配换行符 \n是10,\r是13
        if (buffer[i] == 10 || buffer[i] == 13) {
          if (i > lineStart) {
            // 解码完整的一行字节
            final line = utf8.decode(buffer.sublist(lineStart, i));
            if (line.isNotEmpty) {
              // 按业务逻辑处理完整行,可自行调整适配SSEModel的解析规则
              yield SSEModel.fromData(line);
            }
          }
          // 跳过\r\n的第二个换行符
          if (buffer[i] == 13 && i + 1 < buffer.length && buffer[i+1] == 10) {
            i++;
          }
          lineStart = i + 1;
        }
      }
      // 保留未处理的不完整字节到下一轮
      buffer = buffer.sublist(lineStart);
    }
  } catch (e) {
    print('---ERROR---');
    print(e);
    yield SSEModel(data: '', id: '', event: '');
  }
  await Future.delayed(const Duration(seconds: 1));
}

如果需要兼容包含id、event、多段data的标准SSE事件格式,可以在解析行的逻辑里新增事件字段缓存,遇到空行时再组装成完整的SSE事件对象即可。

内容的提问来源于stack exchange,提问作者Pratik Baid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 06:45:03