96SEO 2026-08-03 21:40 1
痛点一:看到 ChatGPT 那种“打字机”效果。却不知道背后到底用了什么技术,导致在项目里复现时手足无措。
痛点二:大量文档只讲原理。却缺少一步步可运行的代码示例,初学者往往看不懂。
痛点三:在实际开发中。经常会碰到数据被截断、JSON 解析报错、流关闭不明确等坑,缺乏程序化的排查思路。
You 在浏览器里看到的文字、图片、视频,在底层都是0 和 1 组成的二进制数据. 这些数据不是一次性全部到达,而是像水流一样。一小块一小块地流过来.
// 🔤 编码器:把字符串 → 二进制数组
const encoder = new TextEncoder;按理说,const bytes = encoder.encode;console.log,// Uint8Array
// 🔓 解码器:把二进制数组 → 字符串
const decoder = new TextDecoder;const str = decoder.decode;console.log,// "你好"
Uint8Array 是 JavaScript 中的一种类型化数组,只能存放 0~255 范围内的整数。按理说,
Ai 服务端返回的数据*就是*这种 Uint8Array 二进制流。如果不认识它,后面的读取与解码过程将毫无头绪。
ReadableStream 是浏览器原生提供的可读数据流 API,它代表一条可以逐块读取的数据通道。
// fetch 返回一个包含 ReadableStream 的 response
const response = await fetch;按理说,console.log;// ReadableStream { locked: false,... }
// 从 stream 上获取读取器
const reader = response.body.getReader;
// 每次 read 返回 { done: boolean。value: Uint8Array }
const { done,value } = await reader.read;// done === false → 还有数据,继续接
// done === true → 数据已读完
// value → 本次接到的一段二进制
SSE是一种服务器主动向浏览器推送文本数据的协议。
再看data,{"id":"chatcmpl-xxx","choices":}
至于data,{"id":"chatcmpl-xxx"。"choices":}
data的观点是,{"id":"chatcmpl-xxx","choices":}
data这方面,
"data: " 开头;"data: "
npm create vite@latest stream-demo -- --template vue
cd stream-demo
npm install
import { ref } from 'vue';const question = ref;// 使用者输入框
const content = ref;
// AI 回答显示区
const stream = ref;// 流式/普通模式开关
``
Pain Point:content定义为ref`。页面不会自动更新,而只能手动触发渲染。
2️⃣ 调用 AI 接口
const update = async => {
if return;content.value = '思考中...';const endpoint = `${import.meta.env.VITE_MIMO_API_BASE_URL}/chat/completions`;const headers = {
Authorization: `Bearer ${import.meta.env.VITE_MIMO_API_KEY}`。'Content-Type': 'application/json',};说起来,const response = await fetch(endpoint,{
至于method,'POST',headers,body: JSON.stringify({
至于model。import.meta.env.VITE_MIMO_MODEL,messages:,stream: stream.value,// 👈 开启流式返回
}),});/* ---------- 流式处理开始 ---------- */
Pain Point:⚡️ 流式模式主要代码
if {
content.value = '';// ===== 阶段 A:准备工具 =====
const reader = response.body.getReader;怎么说呢,// 获取读取器
const decoder = new TextDecoder;// UTF‑8 解码器
let done = false;let buffer = '';// ===== 阶段 B:循环读取 =====
while {
const { done: doneReading,value } = await reader.read;done = doneReading;不过,
// 把上一次残留 + 本次新块拼起来再解码
const chunkValue = buffer + decoder.decode;buffer = '',// 按换行符切分并过滤出合法行
const lines = chunkValue.split
.filter);// ===== 阶段 C:逐行解析 =====
for {
const raw = line.replace.trim;if { // 收到结束标记
done = true;break,}
try {
const parsed = JSON.parse;const token = parsed.choices?.,.delta?.content,if {
content.value += token;// Vue 响应式自动更新页面
}
} catch {
// JSON 被截断 → 保存到 buffer 等下轮拼接
buffer += line + '
';}
}
}
-
Pain Point #1:`await reader.read` 会阻塞当前 async 函数,但不会卡死 UI;若忘记 `await` 则会得到未决 Promise,引发意外行为。老实说,
阶段细化演示
📦 第一次循环 – 正常两条 token
-
等待
reader.read → 收到第一块
-
解码
decoder.decode → 'data:{...\"从\"}
从data来看,{...\"前\"}
'
-
split & filter 得到两条合法行
-
JSON.parse ➜
"从""前"
-
追加
content.value += token → 页面显示 “从前”
📦 第二次循环 – 数据被截断
-
收到包含
"在" 完整行 + 截断半句
-
完整行正常解析得到
"在" 并追加
-
截断半句
JSON.parse 报错,被捕获后存入 buffer
📦 第三次循环 – 拼接修复
-
新块只剩下被截断部分
"山"}]}
"
-
buffer + newChunk 恢复为完整 JSON 行
-
成功解析得到
"山" 并追加
📦 第四次循环 – 标记
-
最终一块返回
且 doneReading=true
-
循环退出。最终内容 “从前在山”
完整执行流程图
使用者点击提交 ──► fetch POST
│ │
▼ ▼
AI Server 按 token 推送 SSE ──► response.body
│ │ getReader
▼ ▼
while { │
await reader.read ──► Uint8Array chunk
decode │→ string 如 "data:{...}"
split & filter │→ lines
for each line:
strip "data:" →
if "" break →
try JSON.parse →
extract token →
content += token
catch → buffer += line ← 下轮拼接修复}
}
常见坑 & 对策
痛点
描述
推荐方法
变量名冲突
reader.read 返回 {done,value} 与外层控制变量同名
使用解构重命名 {done: doneReading,value}
JSON 被截断
网络分片导致单条 SSE 消息跨块出现
用 buffer 暂存残余,在下一轮拼接后再解析
中文字符乱码
未传 {stream:true} 时中文被切割成非法字符
始终使用 decoder.decode
API Key 泄露
将密钥硬编码在前端源码中
使用 .env.local 并以 VITE_ 前缀暴露,仅供本地调试;老实说,生产环境建议走后端代理
未及时捕获
某些实现只依赖 reader.doneReading 导致最终一句未渲染
同时监听 doneReading && line==="" 双重退出条件
页面模板
{{ content }}
正在思考...
\
<\/div>\
<\/template>\
完整代码汇总
vue
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback