从零开始:前端如何通过 `fetch` 调用 大模型(详解)

在现代 AI 应用开发中,我们经常需要在浏览器端直接调用大语言模型(LLM)的 API。虽然有 OpenAI SDK 等封装工具,但使用原生 fetch 发送 HTTP 请求是一种更灵活、可控且易于理解的方式。

本文将结合你提供的代码和笔记,深入解析 如何在前端通过 fetch 调用 DeepSeek 的聊天接口,并逐行解释每一个关键步骤。


🧩 一、完整的调用代码

javascript 复制代码
// llm api 地址
const endpoint = 'https://api.deepseek.com/chat/completions';

// 请求头
const headers = {
  'Content-Type': 'application/json',
  'Authorization': `Bearer ${import.meta.env.VITE_DEEPSEEK_API_KEY}`
};

// 请求体
const payload = {
  model: 'deepseek-chat',
  messages: [
    { role: 'system', content: 'You are a helpful assistant.' },
    { role: 'user', content: '你好 Deepseek' }
  ]
};

// 发起请求
const response = await fetch(endpoint, {
  method: 'POST',
  headers,
  body: JSON.stringify(payload)
});

// 解析响应
const data = await response.json();
console.log(data);

// 显示结果
document.getElementById('reply').textContent = data.choices[0].message.content;

这段代码实现了从用户输入到模型回复的完整流程。下面我们逐部分拆解。


🔍 二、HTTP 请求结构解析(结合你的笔记)

1. 请求行(Request Line)

bash 复制代码
POST /chat/completions HTTP/1.1
Host: api.deepseek.com
  • POST:必须使用 POST 方法,因为 API 接口要求;
  • /chat/completions:DeepSeek 的聊天接口路径;
  • HTTP/1.1:标准版本,浏览器自动处理。

2. 请求头(Headers)

css 复制代码
{
  'Content-Type': 'application/json',
  'Authorization': 'Bearer sk-xxxxxx'
}
  • 'Content-Type': 'application/json'
    告诉服务器请求体是 JSON 格式,这是必需的。
  • 'Authorization': 'Bearer <key>'
    认证方式,Bearer 是固定前缀,后面跟你的 API Key。

⚠️ 注意:API Key 不能硬编码在前端代码中,应通过 Vite 的环境变量管理:

ini 复制代码
// .env 文件
VITE_DEEPSEEK_API_KEY=sk-xxxxxxxx

在代码中使用 import.meta.env.VITE_DEEPSEEK_API_KEY 获取。


3. 请求体(Body)

css 复制代码
{
  model: 'deepseek-chat',
  messages: [
    { role: 'system', content: 'You are a helpful assistant.' },
    { role: 'user', content: '你好 Deepseek' }
  ]
}
  • model:指定使用的模型名称;

  • messages:对话历史,支持多轮交互;

    • role: "system":设定助手行为;
    • role: "user":用户的提问内容。

✅ 注意:请求体必须是字符串化后的 JSON ,所以要用 JSON.stringify()


4. 使用 fetch 发送请求

javascript 复制代码
const response = await fetch(endpoint, {
  method: 'POST',
  headers,
  body: JSON.stringify(payload)
});
  • method: 'POST':发送 POST 请求;
  • headers:设置请求头;
  • body: JSON.stringify(payload):将 JS 对象转为字符串,不能直接传对象

💡 await.then() 更直观,适合异步操作。


5. 处理响应

ini 复制代码
const data = await response.json();
console.log(data);
  • response.json() 将响应体解析为 JavaScript 对象;
  • data.choices[0].message.content 是模型返回的文本。

6. 显示结果

ini 复制代码
document.getElementById('reply').textContent = data.choices[0].message.content;
  • 将模型回复显示在页面上(假设有一个 id 为 reply 的元素)。

🔄 三、异步处理:.then vs await

你提到:

- await 异步变同步比 then 更方便

✅ 完全正确!

方式 特点
.then() 链式调用,适合复杂逻辑
await 代码像同步一样,更易读

推荐使用 await,尤其是在处理多个异步操作时。


🔐 四、安全建议:API Key 的存放位置

❌ 不推荐(前端暴露)

ini 复制代码
const apiKey = 'sk-xxxxxxxx'; // 直接写在代码里 → 容易泄露

✅ 推荐(后端代理)

javascript 复制代码
// 后端路由
app.post('/api/chat', async (req, res) => {
  const response = await fetch('https://api.deepseek.com/chat/completions', {
    headers: {
      'Authorization': `Bearer ${process.env.DEEPSEEK_API_KEY}` // 后端环境变量,安全!
    },
    body: JSON.stringify(req.body)
  });
  res.json(result);
});

然后前端只调用自己的 /api/chat永远看不到真实 API Key


✅ 五、总结:前端调用 LLM 的核心要点

要点 说明
✅ 使用 fetch 发送 POST 请求 标准方式,兼容性强
✅ 设置 Content-Type: application/json 必须
✅ 添加 Authorization: Bearer <key> 认证必要
✅ 使用 JSON.stringify() 处理请求体 不能直接发送 JS 对象
✅ 使用 await 处理异步 更简洁
✅ 环境变量管理 API Key Vite 支持 VITE_ 开头变量
⚠️ 不要在生产环境中暴露 API Key 必须走后端代理

🎯 结语

技术的本质是解决问题,而不是追求"高大上"的工具。

当你理解了 fetch 的工作原理,就能轻松对接任何符合 OpenAI 协议的 LLM 服务。无论是 DeepSeek、Qwen 还是其他模型,只要你知道它的 API 地址和参数格式,就可以用这段代码快速接入。

希望这篇文章帮你彻底搞懂了前端调用 LLM 的全过程!

如果你正在做项目,我可以帮你封装一个通用的 AI 调用模块 😊

相关推荐
moMo8 小时前
JavaScript 变量提升,执行上下文里的各种门道
javascript·面试
weixin_471383038 小时前
由浅入深递归练习
前端·javascript·vue.js
格桑阿sir8 小时前
10-大模型智能体开发工程师:RAG检索增强生成
ai·大模型·llm·embedding·agent·检索增强·rag
tedcloud1238 小时前
ai-engineering-from-scratch部署教程:从零搭建AI应用环境
服务器·前端·人工智能·系统架构·edge
Kurisu5759 小时前
全面战争:战锤3修改器下载2026最新
前端
丷丩9 小时前
MapLibre GL JS第21课:绘制GeoJSON点图标、注记
前端·javascript·gis·mapbox·maplibre gl js
LCG元9 小时前
现代Web应用高可用架构设计与性能调优实战
前端·wpf
丷丩9 小时前
MapLibre GL JS第20课:更新GeoJSON多边形
前端·javascript·gis·mapbox·maplibre gl js
swipe9 小时前
DeepAgents middleware 工程实战:把复杂 Agent 的运行时基建交给可组合中间件
前端·面试·llm
丷丩10 小时前
MapLibre GL JS第33课:渲染世界副本
javascript·gis·map·mapbox·maplibre gl js