用 SSE 实现 ChatGPT 流式打字机效果,核心是边收边显+视觉拟真:建立 EventSource 连接监听 message 事件,逐段追加服务端推送的 data;通过 CSS 光标动画与渐显过渡增强输入感;并处理空数据、错误重连及超时兜底。

用 JavaScript 的 SSE(Server-Sent Events)实现 ChatGPT 风格的流式打字机效果,核心是监听服务端持续推送的文本片段,逐段追加到页面元素中,并配合 CSS 或 JS 控制光标闪烁和字符渐显节奏。关键不在“一次性渲染”,而在“边收边显”+“视觉拟真”。
建立 SSE 连接并接收流式数据
SSE 是单向、长连接、基于 HTTP 的实时通信方式,适合服务端持续推送响应片段。前端需创建 EventSource 实例,监听 message 事件:
- 确保后端以
text/event-stream响应头返回数据,每条消息以data: xxx\n\n格式分隔 - 前端用
new EventSource(url)初始化连接,推荐加上错误重连逻辑(如网络断开时自动重建) - 每次收到
message事件,event.data就是一小段 token(例如一个词、一个标点或几个字符),不是完整回答
逐字符/逐词追加 + 模拟打字节奏
直接把每次收到的 data 追加到 DOM 容器里会显得生硬。要模拟人工输入感,需控制显示节奏:
- 将新收到的文本拆成字符数组,用
setTimeout或requestAnimationFrame逐个插入(适合精细控制) - 更实用的做法:对每次收到的
data整体追加,但添加transition或animation让新增内容有“浮现”感(如 opacity 渐变) - 避免频繁操作 DOM:可先拼接字符串缓存,再批量更新 innerHTML 或 textContent,减少重排重绘
管理光标与状态反馈
ChatGPT 界面右侧常有动态闪烁的竖线光标,它不是装饰,而是用户感知“正在思考/生成中”的关键信号:
立即学习“Java免费学习笔记(深入)”;
- 用 CSS 实现:给容器末尾伪元素
::after设置content: "|"; animation: blink 1s step-end infinite; - 连接建立后显示光标;收到最终消息(如服务端发
data: [DONE]\n\n)或超时后移除光标 - 可叠加 loading 状态提示(如“AI 正在思考…”),在首次
message到达后再隐藏,增强响应感知
处理边界与容错
真实场景中,SSE 流可能中断、乱序、含空值或格式异常,需主动兜底:
- 检查
event.data是否为空或仅含空白符,跳过无效片段 - 监听
error事件:连接失败时关闭实例、提示用户、尝试重连(带退避策略,如指数增长延迟) - 设置超时:若 30 秒内无新数据且未结束,主动终止连接并提示“响应超时”
- 避免重复渲染:记录已处理的 event ID(如果服务端支持),防止重放导致内容重复


















