You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Cloudflare部署的Svelte服务端流式返回OpenAI API响应?

问题

Svelte文档中给出了在+svelte.js文件中处理POST请求并返回普通响应的示例:

export async function POST({ request }) {
    const { a, b } = await request.json();
    return json(a + b);
}

但文档未提及如何流式返回响应。我需要在POST请求中调用OpenAI API获取流式响应,代码如下:

export async function POST ({ request }) {
    const completion = await openai.chat.completions.create({
        messages: [{ role: "system", content: prompt }],
        model: "gpt-3.5-turbo",
        stream: true,
    });

    for await (const chunk of completion) {
        console.log(chunk.choices[0].delta.content);
    }
}

我需要将每个chunk.choices[0].delta.content逐段流式返回给发起请求的页面。此前用Express时可通过res.write(data)实现流式响应,但Express无法部署在Cloudflare上,因此需要找到适用于Svelte且兼容Cloudflare的等效方法。

解决方案

在SvelteKit(兼容Cloudflare Pages/Workers)中,要实现流式响应,需返回包含ReadableStream的Response对象,替代默认的json()辅助函数,具体实现如下:

基础流式响应实现

export async function POST({ request }) {
    // 解析请求中的参数
    const { prompt } = await request.json();

    const completion = await openai.chat.completions.create({
        messages: [{ role: "system", content: prompt }],
        model: "gpt-3.5-turbo",
        stream: true,
    });

    // 创建可读流处理分块数据
    const stream = new ReadableStream({
        async start(controller) {
            try {
                for await (const chunk of completion) {
                    const content = chunk.choices[0]?.delta?.content;
                    if (content) {
                        // 将文本编码为Uint8Array写入流
                        controller.enqueue(new TextEncoder().encode(content));
                    }
                }
            } catch (error) {
                controller.error(error);
            } finally {
                controller.close();
            }
        }
    });

    // 返回带流式内容的响应
    return new Response(stream, {
        headers: {
            'Content-Type': 'text/plain; charset=utf-8',
            'Transfer-Encoding': 'chunked'
        }
    });
}

Server-Sent Events(SSE)格式适配

如果前端需要用SSE接收响应,只需修改流的写入格式和响应头:

// 在流的start方法中修改写入内容
if (content) {
    controller.enqueue(new TextEncoder().encode(`data: ${content}\n\n`));
}

// 修改响应头
return new Response(stream, {
    headers: {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive'
    }
});

前端接收示例

const response = await fetch('/api/your-endpoint', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ prompt: '你的提示内容' })
});

const reader = response.body.getReader();
const decoder = new TextDecoder();
const outputElement = document.getElementById('output');

while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    const chunk = decoder.decode(value);
    outputElement.textContent += chunk;
}

Cloudflare Workers/Pages原生支持ReadableStream,上述方案完全兼容Cloudflare部署环境。

内容的提问来源于stack exchange,提问作者Jake

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 23:35:54