当前位置: 首页 > news >正文

fetch post请求SSE「eventsource-parser/stream」

随着AI越来越多的进入人们的生活,程序员难免会开发一些AI助手的工作 ,这里记录开发中遇到的一个坑

const response = await fetch('/sse', {method: 'POST',headers: {'Content-Type': 'text/event-stream'},body: {"user_id": 123}})
const reader = response.body.pipeThrough(new TextDecoderStream()).getReader()
while (true) {const {value, done} = await reader.read();if (done) break;console.log('Received', value);
}

这样的代码,就可以完整的使用fetch POST请求到SSE的数据,reader.read() 会一直的循环读取

但是 这里需要自己解析:

得到的格式是:

data: {"event":"message","task_id":"544396bb-b898-467f-833a-11b8393b1064","id":"793f44db-a07d-4be7-96ec-73c08e131ce0","message":"","type":"","url":"","audio":"","answer":"**\n","created_at":1747021789,"conversation_id":"5549a44c-8087-4ac7-9084-af4bee7f481e","workflow_run_id":"","metadata":{"usage":{"prompt_tokens":0,"prompt_unit_price":"","prompt_price_unit":"","prompt_price":"","completion_tokens":0,"completion_unit_price":"","completion_price_unit":"","completion_price":"","total_tokens":0,"total_price":"","currency":"","latency":0},"retriever_resources":null},"from_variable_selector":["17424585111000","text"],"code":"","data":{"id":"","workflow_id":"","sequence_number":0,"node_id":"","node_type":"","title":"","index":0,"created_at":0,"finished_at":0,"status":"","error":"","elapsed_time":0,"predecessor_node_id":""}}

这不是一个对象,是一个字符串,并且如果没有读取完就处理,会出现,JSON截断的情况。

response.then(resp => {resp.data.on('data', data => {const lines = data.toString().split('\n').filter(line => line.trim() !== '')for (const line of lines) {const message = line.replace(/^data: /, '')if (message === '[DONE]') {res.write('data: DONE\n\n')res.end()return}const parsed = JSON.parse(message) // 此处会报错res.write(`data: ${parsed.choices[0].text}\n\n`)}})}).catch(err => {console.log(err)})

尝试了在 JSON.parse处 加上try catch 一旦报错 记录下当前行的值,拼接到下一行的头部。
然后在处理,这种情况理论上也是可行的,但是实际调试非常复杂,字符串分割总有看不见的问题。

eventsource-parser/stream作用是将sse接口返回的字符串转为对象且避免了debug断点时接口不间断返回的数据被塞到一个字符串的问题

是的 只需要读取的时候 改造一下代码

    const reader = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream()).getReader()

就可以在循环的时候直接读取到 每一行的对象数据
在这里插入图片描述

相关文章:

  • 解决 CJSON 浮点数精度问题:从 `cJSON_AddNumberToObject` 到 `cJSON_AddRawToObject`
  • 大项目k8s集群有多大规模,多少节点,有多少pod
  • 基于 Cursor + 浏览器MCP服务 实现 Web端自动化测试
  • 【Dv3Admin】工具数据验证配置文件解析
  • Python-Flask-Dive
  • mapbox进阶,使用mapbox-plugins插件加载饼状图
  • 【Python】Python常用数据类型详解
  • 一周学完计算机网络之三:1、数据链路层概述
  • 安装Hadoop并运行WordCount程序
  • ACL访问控制列表:access-list 10 permit 192.168.10.1
  • MySQL-逻辑架构
  • (五)毛子整洁架构(分布式日志/Redis缓存/OutBox Pattern)
  • 不定长滑动窗口---初阶篇
  • 科技快讯 | 字节跳动开源一款Deep Research项目;全球首个氮化镓量子光源芯片发布
  • 图论拓扑排序
  • Spring Boot动态配置修改全攻略
  • 神经符号推理系统:研究进展与应用前景
  • MCP 入门实战:用 C# 开启 AI 新篇章
  • 文本数据可视化
  • 【软件工程】软件缺陷 基于组合的优化方法
  • 摩根士丹利:对冲基金已加码,八成投资者有意近期增配中国
  • 科普|“小”耳洞也会引发“大”疙瘩,如何治疗和预防?
  • 《新时代的中国国家安全》白皮书(全文)
  • 普京提议无条件重启俄乌谈判,外交部:我们支持一切致力于和平的努力
  • 习近平会见古共中央第一书记、古巴国家主席迪亚斯-卡内尔
  • 深入贯彻中央八项规定精神学习教育中央第七指导组指导督导中国船舶集团见面会召开