前端学习笔记(18)处理sse流式输出 笔记【前端处理sse流式输出】2026年6月9日 22:34什么是sse协议一种服务器向客户端单项推送内容的技术服务器连续的向客户端发送数据每次发送一段纯文本核心的格式规范以标识【data:】开头以【\n\n】两个换行符结尾data:【一次完整的数据内容】\n\nsse还支持以下标识事件【event:】消息id【id:】重连间隔【retry:】dify的sse规范dify基本只发送data标识data的数据内容是json的格式这个json固定有以下属性event数据发送的事件conversation_id数据发送的对话id。下次向dify请求时候带这个就能接上这次对话message_id每次请求的消息iddata除了message事件其他event在这里传关键数据每种event有固定的data格式answermessage事件特有的属性每次传一点LLM流式输出的文本片段dify的sse事件工作流启动event为workflow_started节点开始event为node_started节点结束event为node_finished消息节点event为messagejs接dify的sse返回项目自己封装的$fetch, 是基于axios的用不了0.18.0版本为什么不能用axios这里不能用axios因为axios是对xhr的封装xhr需要等到一次响应完毕才能一次性读到res.data需要用fetch()fetch返回一个浏览器原生response对象res.body是一个ReadableStream实例用这个可以一段一段的获取数据实现方法通过一个异步方法sendDifyMessage向dify发送请求返回值的answer随时间不断变动逐步拼接messageasyncsendDifyMessage({query,conversation_id,files,onMessage}){constparams。。。// 按dify的要求构建参数// 有一个地方要注意params.body.response_mode需要是streamingconstresasyncfetch(DIFY_URL,params)constreaderres.body.getReader()constdecodernewTextDecoder()// 可以使用response.body.getReader().read()异步方法获取流的下一块数据// const {done,chunk1} async reader.read()// const {done,chunk2} async reader.read()// const {done,chunk3} async reader.read()// const {done,chunk4} async reader.read()// 循环获取数据直到dify的数据全部发送完成// 同时每个chunk的格式是Uint8Array需要先解析再拼起来用TextDecoder()解析letbufferletanswer// 不断的刷新数据while(true){const{done,chunk}asyncreader.read()if(done)break//流停止就结束// stream: true避免中途阶段bufferdecoder.decode(value,{stream:true})// 去掉不完整的最后一行// 如果完整传回一行最后必定是\n\npop()去掉的只会是一个空串constlinesbuffer.split(\n)bufferlines.pop()||// 这里的line是一行【标识:数据】for(constlineoflines){// dify的sse只有data需要处理if(!line.startsWith(data: ))continuetry{// 去掉【data: 】剩下的是一个JSON字符串consteventJSON.parse(line.slice(6))// 按if(event.eventmessage){answerevent.answer||if(event.conversation_id)conversation_idevent.conversation_idif(onMessage)onMessage({type:chunk,answer:event.answer,fullAnswer:answer})}elseif(event.eventmessage_end){if(event.conversation_id)conversation_idevent.conversation_idif(onMessage)onMessage({type:end,fullAnswer:answer})}elseif(event.eventerror){if(onMessage)onMessage({type:error,message:event.message})}}catch(e){// 非 JSON 行跳过}}}

相关新闻

最新新闻

跨设备剪贴板共享工程化笔记:可读代码与可复现页面并行推进

跨设备剪贴板共享工程化笔记:可读代码与可复现页面并行推进

手机剪贴板与设备粘贴演示:从输入到历史记录的完整交互 写在前面 很多人第一次看到“跨设备剪贴板”这样的页面标题时,会自然联想到系统级剪贴板、设备发现、账号同步和真正的跨设备传输。不过,判断一个页面能做什么,不能只看标题…

2026/8/25 13:34:41
怎么降低ai率最有效?手动改写+降aigc工具双路线,附检测对比

怎么降低ai率最有效?手动改写+降aigc工具双路线,附检测对比

怎么降低ai率最有效?手动改写降aigc工具双路线,附检测对比 凌晨一点,我收到学妹的消息:论文查重过了,AI率没过,维普报告上写着58.7%,学院要求15%以内,答辩材料三天后截止。她的原话是…

2026/8/25 13:34:41
中小企业数字化转型指南 | 1800款数字化应用背后:中小企业真正想要什么工具

中小企业数字化转型指南 | 1800款数字化应用背后:中小企业真正想要什么工具

本文拆解五大业务环节的差异化工具需求:研发重国产化、生产重非标定制、经管重系统集成、运维重安全防护、供应链重细分适配。总结中小企业数字化工具选型三条铁律,帮助企业精准对号入座、低成本落地、避免资源浪费。一、开篇破局:别把大厂方…

2026/8/25 13:34:41
B站视频转Markdown:4种方法保存到Obsidian,搭建个人知识库

B站视频转Markdown:4种方法保存到Obsidian,搭建个人知识库

如果已经在用Obsidian,B站视频可能是最不好处理的一类学习资料。 网页可以剪藏,PDF可以放进Vault,文字天然可以全文搜索。但一个两个小时的课程,本质上还是一个只能顺着时间播放的线性文件。 所以真正值得解决的问题不是“怎么收…

2026/8/25 13:34:41
[论文学习]让Agent击败Agent:基于LLM的Agent中汙点型漏洞的自动检测(AgentFuzz / AutoMalTool)

[论文学习]让Agent击败Agent:基于LLM的Agent中汙点型漏洞的自动检测(AgentFuzz / AutoMalTool)

Make Agent Defeat Agent: Automatic Detection of Taint-Style Vulnerabilities in LLM-based Agents (AgentFuzz, USENIX Security 2025) 论文重点 本文提出了AutoMalTool,首个针对LLM-based Agent的自动化红队测试框架,通过多智能体协作自动生成可规…

2026/8/25 13:34:41
智能体面试准备(五十四):智能体线上实验与效果归因体系——上线决策科学

智能体面试准备(五十四):智能体线上实验与效果归因体系——上线决策科学

智能体面试准备(五十四):智能体线上实验与效果归因体系——上线决策科学 引言:为什么"离线评测高分"不等于"线上能发" B31 讲过 Agent 评测体系(轨迹指标、LLM-as-Judge、benchmark)&a…

2026/8/25 13:29:40