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", ... }

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

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,省心省力,错误处理更完善
  • 调用多个模型 → 改一下 baseURLapiKey 就能无缝切换

💡 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 ⭐

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

相关推荐
计算机安禾1 小时前
【算法分析与设计】第49篇:算法博弈论与机制设计
人工智能·算法·机器学习
程序员契奇1 小时前
12_Agent的Hook补充+控制Agent+流式输出+总结
人工智能·agent
深圳市机智人激光雷达1 小时前
激光雷达:智慧港口自动化升级的核心感知基石
运维·人工智能·机器人·自动化·自动驾驶·无人机·激光雷达
哈哈,柳暗花明1 小时前
人工智能专业术语详解(F)
人工智能·专业术语
xiaofeichaichai1 小时前
Symbol 与 Iterator / Generator
前端·javascript
PKUMOD1 小时前
SIGMOD2026 | NeuSO:面向子图查询的学习型优化器
人工智能
linge_sun1 小时前
SpringAI 功能体验之SQL智能助手:用自然语言查询数据库
java·人工智能·ai编程
Hotchip_MEMS1 小时前
旧路由器拆出“功臣芯片”:AMS1117在高温下工作8年,只消耗2mA静态电流
网络·人工智能·物联网·智能路由器
Alluxio1 小时前
造父智能(哈啰robotaxi)在阿里云环境下构建极致透明的训练加速层
人工智能·机器学习·缓存·系统架构·自动驾驶·模型训练