专业编程教程与实战项目分享平台

网站首页 > 技术文章 正文

AI对话, 流式输出响应, 前端对接解析

ins518 2025-09-13 01:11:34 技术文章 1 ℃ 0 评论

在 AI 对话场景中,流式输出是提升用户体验的关键技术 —— 它能让 AI 响应像人类对话一样 “逐句呈现”,而非让用户等待完整内容加载完毕,尤其适合长文本生成(如万字报告、多轮复杂对话)。前端对接流式输出的核心,是理解 “服务器如何分块推送数据” 以及 “前端如何实时解析、渲染这些数据”,以下是结合本人自身开发的实际项目做一些解析, 希望对有意对接AI, 开发自身应用的小伙伴有一些帮助, 少走一些弯路。

一、先搞懂:AI 流式输出的底层逻辑

传统接口请求是 “请求 - 全量响应” 模式(前端发请求→服务器生成完整内容→一次性返回),而流式输出是 “请求 - 分块响应” 模式,核心依赖 HTTP/2 或 HTTP/1.1 的 Chunked Transfer Encoding(分块传输编码)—— 服务器无需等待所有内容生成,每生成一段文本就封装成一个 “数据块” 推送给前端,前端接收一块渲染一块。

具体流程如下:

前端:发起流式请求(需在请求头中声明 “接受分块数据”);

后端 / AI 服务:收到请求后,启动 AI 生成任务,按 “句子 / 段落” 粒度拆分生成结果;

传输层:服务器通过 Chunked 编码,将每个数据块标记长度(如5\r\nhello\r\n),逐块发送;

前端:监听 “数据块接收” 事件,每收到一块就解析内容,追加到页面对话区;

结束标识:服务器发送 “空数据块”(0\r\n\r\n),表示流式传输结束,前端关闭连接。

二、前端对接核心方案:按技术栈分类

前端对接流式输出的核心是 “监听数据流”,不同技术栈(原生 JS、Vue2)的实现逻辑一致,但语法细节有差异,以下是落地性极强的实战方案。

原生 JavaScript(无框架通用)

依赖浏览器原生的 Fetch API(支持流式响应)或 new EventSource,推荐用 Fetch(更简洁,支持 ReadableStream)。

关键步骤:

发起流式请求:在 fetch 中设置请求头 Accept: text/event-stream(告诉服务器 “我要流式数据”),且需关闭缓存(Cache-Control: no-cache);

处理响应流:通过 response.body.getReader() 获取 “数据读取器”,循环读取每一块数据;

解码与解析:AI 返回的分块数据是 Uint8Array 格式,需用 TextDecoder 转成字符串,再按后端约定格式解析(如 JSON、SSE 格式);

实时渲染:每解析出一段有效文本,就追加到对话 DOM 中,避免频繁重绘(建议用 textContent 而非 innerHTML,防止 XSS)。

vue2 中 Fetch示例:




vue2 中 new EventSource示例 这个只支持get方式请求:



三、关键细节:避坑与体验优化

前端对接流式输出时,容易遇到 “解析乱码”“渲染卡顿”“断流” 等问题,以下是必须注意的细节:

1. 数据格式解析:避免 “拆包” 导致的 JSON 错误

AI 服务返回的流式数据可能有两种格式,解析逻辑不同:

SSE(Server-Sent Events)格式:标准流式格式,每块以 data: 开头,换行分隔(如 data: {"content":"你好"}\n\ndata: {"content":"今天..."}),需过滤空行、去掉 data: 前缀,再解析 JSON;

纯文本 / JSON 分块:后端直接按文本片段推送(如 “你好”→“今天天气不错”),或按 JSON 数组推送(如 ["你好","今天..."]),需确保 “每块是完整的 JSON”(后端需避免将一个 JSON 拆成多个块,否则前端解析会报错)。

避坑点:若后端返回 JSON 分块,需在后端做 “边界处理”(如按句子结束符分割),前端若遇到 JSON 解析错误,可暂存不完整的分块,待下一块到来后拼接再解析。

数据包的拆分与续接可参考下面代码:

2. 编码统一:防止中文乱码

服务器返回的分块数据是二进制(Uint8Array),前端需用 TextDecoder 转码,必须指定正确的编码格式(默认是 utf-8,但部分后端可能用 gbk),否则会出现中文乱码。

3.vue本地开发, 后端按流式返回,前端却没有流式输出而是一次性输出

这个需要看下前端代理配置,需要自行处理, 去除缓存,禁止代理自动处理数据,这是我项目的代理配置,仅供参考

4. ai对话流一般输出的都是使用markdown语法,还有公式也是需要处理, 能使界面美观

在项目中可以安装"katex": "^0.15.2", "marked": "^5.0.0", marked可以将markdown语法转为 html, vue里面用v-html展示即可, katex可以美化公式相关的展示

import marked from 'marked';

import katex from 'katex';

import 'katex/dist/katex.min.css'; // 引入KaTeX样式


然后在需要使用的地方调用 this.renderMathInElement(this.marked.parse(this.curStr,{ mangle: false, headerIds: false, highlight: null, langPrefix: ''})) 这样就可以了. mangle: false, headerIds: false, highlight: null, langPrefix: ''这些配置是用来解决marked的语法警告, this.curStr是AI对话流返回的markdown语法数据

ai流式输出的前端对接大体上就上面那些内容, 欢迎大家一起探讨, 觉得对你有帮助就帮忙点个赞, 有不清楚的可以评论留言



本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表