要实现通过 API 将流式内容输出到前端,可以采用以下技术方案(以 Python 后端 + 前端 JavaScript 为例):

方案一:使用 Server-Sent Events (SSE)

这是浏览器原生支持的流式传输方案,推荐首选

# Flask 示例
from flask import Response, stream_with_context @app.route('/stream')
def stream_data():
def generate():
response = client.chat.completions.create(
model="deepseek-chat",
messages=messages,
stream=True
) for chunk in response:
if chunk.choices:
content = chunk.choices[0].delta.content or ""
# SSE 格式要求 data: 前缀和双换行符
yield f"data: {json.dumps({'content': content})}\n\n" return Response(stream_with_context(generate()), mimetype='text/event-stream')
// 前端 JavaScript
const eventSource = new EventSource('/stream'); eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
document.getElementById('output').innerHTML += data.content;
}; eventSource.onerror = (err) => {
console.error('EventSource failed:', err);
eventSource.close();
};

方案二:使用流式 HTTP 响应(NDJSON)

更通用的流式传输方案,适合非浏览器客户端

# FastAPI 示例
from fastapi import APIRouter
from fastapi.responses import StreamingResponse
import json @app.get("/stream")
async def stream_data():
async def generate():
response = client.chat.completions.create(
model="deepseek-chat",
messages=messages,
stream=True
) async for chunk in response:
if chunk.choices:
content = chunk.choices[0].delta.content or ""
yield json.dumps({"content": content}) + "\n" # NDJSON 格式 return StreamingResponse(generate(), media_type='application/x-ndjson')
// 前端 JavaScript 使用 Fetch API
async function streamData() {
const response = await fetch('/stream');
const reader = response.body.getReader();
const decoder = new TextDecoder(); while(true) {
const { done, value } = await reader.read();
if(done) break; const chunk = decoder.decode(value);
const data = JSON.parse(chunk);
document.getElementById('output').innerHTML += data.content;
}
}

关键配置说明

  1. 响应头设置

    # Flask
    headers = {
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive'
    } # FastAPI 自动处理
  2. 数据格式选择

    • SSE (text/event-stream):浏览器原生支持,自动重连
    • NDJSON (application/x-ndjson):更通用的流式 JSON 格式
    • 纯文本流:简单但结构化能力弱
  3. 前端处理建议

    // 更健壮的读取方式(处理分块不完整情况)
    let buffer = ''; async function processChunk(chunk) {
    buffer += chunk;
    while(buffer.includes('\n')) {
    const lineEnd = buffer.indexOf('\n');
    const line = buffer.slice(0, lineEnd);
    buffer = buffer.slice(lineEnd + 1); try {
    const data = JSON.parse(line);
    // 处理数据...
    } catch(e) {
    console.error('解析错误:', e);
    }
    }
    }

完整工作流程示例(FastAPI + React)

后端

# main.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware app = FastAPI() app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
) @app.get("/chat")
async def chat_stream(prompt: str):
async def generate():
response = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content": prompt}],
stream=True
) async for chunk in response:
if content := chunk.choices[0].delta.content:
yield json.dumps({"content": content}) return StreamingResponse(generate(), media_type="application/x-ndjson")

前端 React 组件

// ChatComponent.jsx
import { useState } from 'react'; export default function ChatComponent() {
const [output, setOutput] = useState(''); const startStream = async () => {
const response = await fetch('http://api/chat?prompt=你好');
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = ''; while(true) {
const { done, value } = await reader.read();
if(done) break; buffer += decoder.decode(value);
while(buffer.includes('}')) {
const endIndex = buffer.indexOf('}') + 1;
const chunk = buffer.slice(0, endIndex);
buffer = buffer.slice(endIndex); try {
const data = JSON.parse(chunk);
setOutput(prev => prev + data.content);
} catch(e) {
console.error('解析错误:', e);
}
}
}
}; return (
<div>
<button onClick={startStream}>开始对话</button>
<div id="output">{output}</div>
</div>
);
}

注意事项

  1. 连接管理

    • 设置合理的超时时间(通常 30-60 秒)
    • 处理客户端提前断开连接的情况
    # FastAPI 示例
    try:
    async for chunk in response:
    # ...处理数据
    if await request.is_disconnected():
    break
    finally:
    await client.close() # 清理资源
  2. 性能优化

    • 使用异步框架(FastAPI 性能优于 Flask)
    • 启用响应压缩
    app = FastAPI()
    @app.middleware("http")
    async def add_compression(request, call_next):
    response = await call_next(request)
    response.headers["Content-Encoding"] = "gzip"
    return response
  3. 安全考虑

    • 限制最大并发连接数
    • 实施速率限制
    from fastapi import Request
    from fastapi.middleware import Middleware
    from slowapi import Limiter
    from slowapi.util import get_remote_address limiter = Limiter(key_func=get_remote_address)
    app.state.limiter = limiter @app.get("/chat")
    @limiter.limit("10/minute")
    async def chat_stream(request: Request):
    # ...
  4. 错误处理增强

    async def generate():
    try:
    response = client.chat.completions.create(...)
    async for chunk in response:
    # 处理数据...
    except Exception as e:
    yield json.dumps({"error": str(e)})
    finally:
    await client.close() # 确保释放资源

这些方案可根据具体需求组合使用,建议优先选择 SSE 方案(浏览器兼容性好),需要支持更复杂场景时可考虑 WebSocket,但后者实现成本较高。

通过 API 将Deepseek响应流式内容输出到前端的更多相关文章

  1. HttpURLConnection的流式输出的缺陷和解决方法

    转自:http://www.mzone.cc/article/198.html 最近在用applet写文件上传控件的时候发现使用URLConnection来对服务器进行流式输出时的一些问题.我们通常要 ...

  2. Java8 流式 API(`java.util.stream`)

    熟悉 ES6 的开发者,肯定对数组的一些方法不是很陌生:map.filter 等.在对一组对象进行统一操作时,利用这些方法写出来的代码比常规的迭代代码更加的简练.在 C♯ 中,有 LINQ 来实现.那 ...

  3. ASP.NET Core Web API 流式返回,逐字显示

    Websocket.SSE(Server-Sent Events)和长轮询(Long Polling)都是用于网页和服务端通信的技术. Websocket是一种全双工通信协议,能够实现客户端和服务端之 ...

  4. CSS3与页面布局学习笔记(四)——页面布局大全(负边距、双飞翼、多栏、弹性、流式、瀑布流、响应式布局)

    一.负边距与浮动布局 1.1.负边距 所谓的负边距就是margin取负值的情况,如margin:-100px,margin:-100%.当一个元素与另一个元素margin取负值时将拉近距离.常见的功能 ...

  5. Openresty的同步输出与流式响应

    Openresty的同步输出与流式响应 默认情况下, ngx.say和ngx.print都是异步输出的,先来看一个例子: location /test { content_by_lua_block { ...

  6. 静态布局、自适应布局、流式布局、响应式布局、弹性布局简析、BFC

    静态布局:给页面元素设置固定的宽度和高度,单位用px,当窗口缩小,会出现滚动条,拉动滚动条显示被遮挡内容.针对不同分辨率的手机端,分别写不同的样式文件.例如:浏览器窗口是1000px,那么最小的宽度是 ...

  7. Django的视图流式响应机制

    Django的视图流式响应机制 Django的响应类型:一次性响应和流式响应. 一次性响应,顾名思义,将响应内容一次性反馈给用户.HttpResponse类及子类和JsonResponse类属于一次性 ...

  8. Hadoop_11_HDFS的流式 API 操作

    对于MapReduce等框架来说,需要有一套更底层的API来获取某个指定文件中的一部分数据,而不是一整个文件 因此使用流的方式来操作 HDFS上的文件,可以实现读取指定偏移量范围的数据 1.客户端测试 ...

  9. 流式布局&固定宽度&响应式&rem

    我们现在在切页面布局的使用常用的单位是px,这是一个绝对单位,web app的屏幕适配有很多中做法,例如:流式布局.限死宽度,还有就是通过响应式来做,但是这些方案都不是最佳的解决方法. 1.流式布局: ...

  10. jackson 流式API

    http://www.cnblogs.com/lee0oo0/articles/2652528.html Jackson提供了三种可选的JSON处理方法 1.流式API     com.fasterx ...

随机推荐

  1. H2数据库用户自定义函数方法及范例

    H2数据库,是Java实现的内存数据库.可使用它作为嵌入式内存数据库,但就其特性还用更多值得应用在实际项目中的意义.之前的一篇Blog中已经描述过其使用方法及丰富的连接数据库方式. 官方主页:http ...

  2. 网页转换成电脑exe软件简单办法

    准备windows电脑,其他电脑步骤差不多 1.安装nodejs(nodejs自带npm),前往nodejs官网下载,选择Windows 安装包 (.msi) 64位,一直点击下一步安装即可 2.wi ...

  3. Qt5离线安装包无法下载问题解决办法

    1.前言 Qt5离线安装包目前在国内已经被墙了,无法下载,只能下载在线安装包: 直接访问会显示Download from your IP address is not allowed: 本文就提出两种 ...

  4. 微服务实战系列(七)-网关springcloud gateway-copy

    1. 场景描述 springcloud刚推出的时候用的是netflix全家桶,路由用的zuul,但是据说zull1.0在大数据量访问的时候存在较大性能问题,2.0就没集成到springcloud中了, ...

  5. 第六章 (Nginx+Lua)Web开发实战HTTP服务

    此处我说的HTTP服务主要指如访问京东网站时我们看到的热门搜索.用户登录.实时价格.实时库存.服务支持.广告语等这种非Web页面,而是在Web页面中异步加载的相关数据.这些服务有个特点即访问量巨大.逻 ...

  6. MySQL---锁、变量、存储过程、游标、自定义函数

    一概述 数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则.对于任何一种数据库来说都需要有相应的锁定机制. MySQL各存储引擎使用了三种类型 ...

  7. DeepSeek V3 两周使用总结

    2024 年 12 月 26 日,杭州深度求索人工智能基础技术研究有限公司发布 DeepSeek-V3 大模型.官方宣称:(1)基于自研的 MoE 模型和 671B 参数,在 14.8T token ...

  8. GD32F4xx FLASH存储

    一.GD32F4xx的内存 GD32F4xx的内存结构由:主存储器.系统信息存储器.一次性编程区域和选项字节等 4 部分组成. 主存储器:用来存放代码和数据常数(如 const 类型的数据).分为 2 ...

  9. 腾讯云 TI 平台部署与调用DeepSeek-R1大模型的实战指南

    今天我们将继续探讨如何部署一个私有化的 DeepSeek-R1 大模型,具体的部署过程我们将利用腾讯云的 TI 平台进行操作.当前,腾讯云 TI 平台为用户提供了免费体验的满血版 DeepSeek-R ...

  10. Serverless函数计算介绍

    本文分享自天翼云开发者社区<Serverless函数计算介绍>,作者:余凯 随着互联网和移动互联网的快速发展,越来越多的应用程序需要具备高可用性.高扩展性和高性能等特点.而云计算作为一种新 ...