5 个 Step,让你的前端代码连上 AI 大模型

5 个 Step,让你的前端代码连上 AI 大模型

🔗 项目源码:gitee.com/zhou-wenqia...

前言

"前端不就是切页面的吗?"

如果你也被这样问过,这篇文章就是你的反击武器。从请求后端数据,到调用 AI 大模型,前端能做的事远比你想象的多------而这一切,只需要掌握一个 API:fetch。

本文通过 5 个 Step,带你从零做到这件事:

Step 做什么 核心技能
1 理解 HTTP 请求 请求行、请求头、请求体
2 搭建后端 json-server、REST API
3 fetch GET 获取数据 async/await、DOM 渲染
4 fetch POST 调用 AI Headers、Body、认证
5 用 SDK 简化代码 OpenAI SDK、baseURL 切换

读完你会发现:会用 fetch,你就能连接整个互联网。


Step 1:理解 HTTP 请求

在写代码之前,先搞清楚 HTTP 请求长什么样。

1.1 请求的三要素

每次 fetch 发出的请求,都由三部分组成:

bash 复制代码
请求行:去哪里、做什么    →  POST /v1/chat/completions
请求头:携带的附加信息    →  Content-Type: application/json
请求体:发送的数据        →  { "model": "mimo-v2.5-pro", ... }

用浏览器打开任意网页,按 F12 → Network 面板,你能看到每一个请求的这三部分。

1.2 Endpoint(端点)

bash 复制代码
http://localhost:3000/friends           ← 本机服务器
https://api.xiaomimimo.com/v1/chat/completions  ← 远程 AI 服务

Endpoint 就是 API 请求的终点------一个"服务窗口",你告诉它你要什么,它返回对应的数据。

  • localhost:3000 → 你本机运行的服务器
  • api.xiaomimimo.com → 远程部署的 AI 服务
  • 域名通过 DNS 解析翻译成 IP 地址,帮你找到对应的服务器

1.3 为什么选 fetch?

前端发 HTTP 请求有三种方式:

方式 特点
fetch 浏览器原生,返回 Promise,推荐
XMLHttpRequest 老牌 API,回调风格,逐渐被淘汰
Axios 等库 封装了 fetch,功能更丰富,需安装

本文全程用 fetch------零依赖,够用且优雅。


Step 2:搭建后端(json-server)

我们先搭一个本地后端,提供数据接口。

2.1 项目结构

kotlin 复制代码
demo1/
├── backend/          ← 后端
│   ├── data.json     ← 数据源
│   └── package.json
└── frontend/         ← 前端
    ├── index.html
    └── main.js

2.2 创建数据文件

在 backend 目录下创建 data.json:

data.json:

json 复制代码
{
    "friends": [
        { "id": 1, "name": "小金", "age": 17 },
        { "id": 2, "name": "大金", "age": 17 }
    ]
}

2.3 安装并启动服务

bash 复制代码
# 创建项目目录并进入
mkdir backend && cd backend

# 初始化项目并安装 json-server
pnpm init
pnpm add json-server@1.0.0-beta.15

然后在 package.json 中添加启动脚本:

json 复制代码
{
    "scripts": {
        "dev": "json-server --watch data.json --port 3000"
    },
    "dependencies": {
        "json-server": "1.0.0-beta.15"
    }
}

如果从零创建,直接运行:

bash 复制代码
pnpm dev

如果克隆了项目源码,先安装依赖再启动:

bash 复制代码
cd demo1/backend
pnpm install
pnpm dev

看到以下输出说明启动成功:

bash 复制代码
  \{^_^}/ hi!

  Loading data.json
  Done

  Resources
  http://localhost:3000/friends

  Home
  http://localhost:3000

json-server 会把一个 JSON 文件变成完整的 REST API:

bash 复制代码
GET    /friends       → 获取所有朋友
GET    /friends/1     → 获取 id 为 1 的朋友
POST   /friends       → 新增朋友
PUT    /friends/1     → 修改朋友信息
DELETE /friends/1     → 删除朋友

💡 这就是前后端分离的核心:后端只管数据(JSON),前端只管展示(HTML/CSS/JS),两者通过 HTTP 接口通信。


Step 3:fetch GET 获取数据

确保 Step 2 的后端已启动(pnpm dev),然后继续。

后端有了,现在用前端代码把数据"拿"过来。

3.1 HTML 页面

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <header><h1>Friends List</h1></header>
    <main>
      <table>
        <thead>
          <tr><th>id</th><th>name</th><th>age</th></tr>
        </thead>
        <tbody>
          <!-- 数据由 JS 动态填充 -->
        </tbody>
      </table>
    </main>
    <footer><p>Powered by json-server + fetch</p></footer>
    <script src="./main.js"></script>
</body>
</html>

3.2 核心 JS 代码

js 复制代码
// 1. 获取数据
async function loadData() {
    const endpoint = 'http://localhost:3000/friends';
    const res = await fetch(endpoint);    // 发送 GET 请求

    if (!res.ok) {                        // fetch 不会因 4xx/5xx 报错,必须手动检查
        throw new Error(`请求失败: ${res.status}`);
    }

    const data = await res.json();        // 响应体是二进制流,要转成 JS 对象
    return data;
}

// 2. 渲染到页面
function renderData(friends) {
    const oBody = document.querySelector('table tbody');
    if (friends.length > 0) {
        // 数据来自本地 json-server(可信来源),用 innerHTML 渲染表格
        // 如果数据来自用户输入或外部 API,应使用 textContent 防止 XSS
        oBody.innerHTML = friends.map(friend => `
            <tr>
                <td>${friend.id}</td>
                <td>${friend.name}</td>
                <td>${friend.age}</td>
            </tr>
        `).join("");
    }
}

// 3. 入口:先加载,再渲染
async function init() {
    try {
        const friends = await loadData();
        renderData(friends);
    } catch (err) {
        console.error('加载数据失败:', err);
    }
}

init();

3.3 关键点拆解

await fetch(endpoint) 做了什么?

scss 复制代码
init() 被调用
  → loadData() 开始执行
    → fetch 发出请求(JS 不阻塞,继续执行其他代码)
    → 响应返回,await 拿到 res
    → res.json() 解析数据
    → await 拿到 data
  → loadData() 返回 data
  → renderData(data) 渲染到 DOM

为什么要检查 res.ok?

fetch 只有在网络错误时才会 reject。HTTP 404、500 这些状态码不会抛异常------你必须自己判断。

为什么要 await res.json()?

res 的 body 是二进制流 ,不是 JS 对象。.json() 把它解析为数组/对象,这一步也是异步的。

async/await 会阻塞浏览器吗?

js 复制代码
console.log('A: 先执行');
const data = await loadData();  // 暂停当前函数,让出线程
console.log('B: 数据到了');      // 数据返回后才执行
// 输出:A → (等待) → B
// 不是 A → B → (等待)

await 只是暂停了当前 async 函数,主线程继续执行其他代码,所以不会卡住浏览器。

3.4 运行效果

用 Live Server 打开 demo1/frontend/index.html,表格自动渲染:

id name age
1 小金 17
2 大金 17

Step 4:fetch POST 调用 AI

现在来玩点更刺激的------用前端代码直接调用 AI 大模型。

4.1 项目结构

复制代码
demo/
├── index.html
├── script.js
└── style.css    ← 可选样式,不影响核心逻辑

4.2 核心代码

前往 api.xiaomimimo.com 注册并获取 API Key,替换下方代码中的 your-api-key-here。

js 复制代码
// endpoint
const endpoint = 'https://api.xiaomimimo.com/v1/chat/completions'

// API Key(生产环境应从环境变量获取,不要硬编码)
const apiKey = 'your-api-key-here'

// 请求头:声明格式 + 身份认证
const headers = {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${apiKey}`
}

// 请求体:模型 + 对话内容
const payload = {
    model: "mimo-v2.5-pro",
    messages: [
        { role: 'system', content: 'You are a helpful assistant' },
        { role: 'user', content: 'hello' }
    ]
}

try {
    const response = await fetch(endpoint, {
        method: 'POST',
        headers,
        body: JSON.stringify(payload)   // body 必须是字符串,不能是对象
    })

    if (!response.ok) {
        throw new Error(`请求失败: ${response.status}`)
    }

    const data = await response.json();
    document.getElementById('reply').textContent = data.choices[0].message.content;
} catch (err) {
    console.error('请求出错:', err);
    document.getElementById('reply').textContent = '请求失败,请查看控制台';
}

4.3 和 Step 3 的三个区别

对比两个 Step 的 fetch 调用:

js 复制代码
// Step 3:GET(最简形式)
fetch('http://localhost:3000/friends')

// Step 4:POST(完整形式)
fetch(endpoint, {
    method: 'POST',
    headers,
    body: JSON.stringify(payload)
})

区别一:请求方法

方法 语义 有无请求体
GET 获取资源 无
POST 提交数据 有
PUT 更新资源 有
DELETE 删除资源 无

区别二:请求头

js 复制代码
const headers = {
    'Content-Type': 'application/json',   // 告诉服务器:我发的是 JSON
    Authorization: `Bearer ${apiKey}`      // 告诉服务器:我是合法用户
}
  • Content-Type:服务器据此决定如何解析 body
  • Authorization:身份认证,大部分 AI API 都需要

区别三:请求体

HTTP 协议传输的只能是字符串 。JSON.stringify() 把 JS 对象序列化为 JSON 字符串。

4.4 请求与响应对照

请求:

bash 复制代码
POST /v1/chat/completions HTTP/1.1
Content-Type: application/json
Authorization: Bearer sk-xxxxxxxx

{
    "model": "mimo-v2.5-pro",
    "messages": [
        { "role": "system", "content": "You are a helpful assistant" },
        { "role": "user", "content": "hello" }
    ]
}

响应:

css 复制代码
HTTP/1.1 200 OK
Content-Type: application/json

{
    "choices": [{
        "message": {
            "content": "Hello! How can I help you today?"
        }
    }]
}

4.5 运行

bash 复制代码
# 1. 替换 script.js 中的 apiKey 为你的实际 Key
# 2. 用 Live Server 打开 demo/index.html(type="module" 不支持 file:// 协议)
# 3. 打开浏览器控制台查看完整响应,页面上会显示 AI 的回复

运行后,页面上会显示:

bash 复制代码
Hello! How can I help you today?

Step 5:用 SDK 简化代码

Step 4 的代码能跑,但有不少重复:手动写 Headers、JSON.stringify、状态码检查......

在实际项目中,大多数开发者会选择 OpenAI SDK 。现在很多大模型服务都兼容 OpenAI 的接口格式,一套 SDK 就能调用多种模型。

5.1 安装

bash 复制代码
npm install openai
# 或
pnpm add openai

5.2 代码对比

同样的功能,用 SDK 只需要:

js 复制代码
import OpenAI from 'openai';

const client = new OpenAI({
    apiKey: 'your-api-key-here',
    baseURL: 'https://api.xiaomimimo.com/v1'
});

try {
    const response = await client.chat.completions.create({
        model: "mimo-v2.5-pro",
        messages: [
            { role: 'system', content: 'You are a helpful assistant' },
            { role: 'user', content: 'hello' }
        ]
    });
    console.log(response.choices[0].message.content);
} catch (err) {
    console.error('请求失败:', err.message);
}

没有 Headers、没有 JSON.stringify、没有 res.ok 检查------SDK 全帮你搞定了。

5.3 fetch vs SDK

fetch(手动) OpenAI SDK
安装依赖 无 需要 npm install openai
Headers 手动写 自动处理
请求体 手动 JSON.stringify 自动序列化
状态码检查 手动 res.ok 自动抛出错误
类型提示 无 完整 TypeScript 类型
流式输出 手动解析 SSE 内置 .stream()
适合场景 学习原理、简单脚本 生产项目、多模型切换

5.4 什么时候用什么?

  • 学习阶段 → 用 fetch,理解底层原理(本文的重点)
  • 生产项目 → 用 SDK,省心省力,错误处理更完善
  • 调用多个模型 → 改一下 baseURL 和 apiKey 就能无缝切换

💡 DeepSeek、Moonshot、智谱、百川等国产大模型都提供 OpenAI 兼容接口,一套代码适配多个服务。


总结

5 个 Step 回顾

vbnet 复制代码
Step 1: HTTP 请求 = 请求行 + 请求头 + 请求体
Step 2: json-server 把 JSON 文件变成 REST API
Step 3: fetch GET + async/await → 从后端拿数据,渲染到页面
Step 4: fetch POST + Headers + Body → 调用 AI 大模型
Step 5: OpenAI SDK → 一行代码搞定,多模型通用

核心范式

js 复制代码
const res = await fetch(url, options);  // 发请求
const data = await res.json();          // 解响应

从获取本地朋友列表,到调用远程 AI 大模型,变化的是 URL、Headers 和 Body,不变的是 fetch + async/await 这套范式。

掌握了这个范式,前端就不再只是"切页面"------你可以连接任何服务,构建真正有生命力的应用。

下一步

  • 🔄 流式输出 :AI 场景的核心体验,用 SSE 或 ReadableStream 实现
  • 🔐 安全:API Key 放后端代理,不要暴露在前端代码中
  • 📦 封装 :把 fetch 封装成自己的 request 工具函数,统一错误处理
  • 🌐 更多 API:天气、地图、支付......万物皆可 fetch

📚 参考资料

👨‍💻 作者:zhou-wenqiang-c | 欢迎 Star ⭐

如果这篇文章对你有帮助,点个赞 👍 收藏 ⭐ 不迷路!有问题欢迎评论区交流~

相关推荐
小炫y5 分钟前
基于规则的NLP技术-词的处理
人工智能·自然语言处理
EatFan11 分钟前
React 项目踩坑实录:useEffect 闭包陷阱、Context 性能陷阱与 React 18 升级避坑排查手册
前端·javascript·react.js·react·react hooks·useeffect·闭包陷阱
冬奇Lab12 分钟前
LLM 驱动的自动化测试系列(09):移动端自动化(五)——当通用 Agent 框架下沉到测试场景
人工智能·agent·测试
冬奇Lab13 分钟前
开源项目第233期:Open-XiaoAI — 刷机接管小米小爱音箱,接入 ChatGPT/小智 AI/Gemini Live
人工智能·开源·资讯
Sayai18 分钟前
MCP Server 开发实战:Spring AI 把后端日志查询暴露给 AI Agent(7 条设计原则与踩坑实录)
java·人工智能·ai agent·spring ai·mcp
阿_旭31 分钟前
【AI前沿】GTR:一套网络通吃检测/分割/姿态/深度六大任务,对标YOLO26
人工智能
AI你一生一世33 分钟前
当一句自然语言指令穿透三层抽象:从“把按钮改成蓝色“看 AI 编码代理的真实边界
人工智能·自然语言处理·前端架构·技术债·设计令牌·ai编码代理·代码抽象
袋鼠云数栈39 分钟前
非结构化数据也能“周期调度“:离线开发BatchWorks的多模态数据同步实践
大数据·人工智能·多模态数据·离线开放
算了吧956943 分钟前
GEO服务商选型指南:2026年企业评估框架与决策路径
大数据·人工智能·物联网
workflower44 分钟前
矿用机器人人工智能安全与治理体系
人工智能·安全·机器学习·机器人·云计算·无人机