在 AI 应用快速普及的今天,大语言模型(LLM)不再只是后端服务的专属能力。通过标准的 HTTP 接口,前端应用也能直接与模型对话------无需中间服务器,只需一个 API Key 和几行代码。本文将带你从零开始,使用原生 HTML/JavaScript 搭建一个能调用 DeepSeek 大模型的前端项目,并深入解析如何安全、规范地发起复杂请求。
项目初始化:选择合适的开发脚手架
虽然纯 HTML 文件足以完成基础调用,但现代前端开发更推荐使用工程化工具提升效率。Vite 是目前最轻量且功能强大的全栈脚手架之一,支持 TypeScript、环境变量、热更新等特性。
首先,初始化一个 Vite 项目:
perl
npm create vite@latest my-llm-app -- --template vanilla
cd my-llm-app
npm install
这会创建一个基于原生 JavaScript 的项目结构,包含 index.html 和 main.js,非常适合快速集成 LLM 调用逻辑。
理解 LLM 的 HTTP 调用协议
大模型 API 本质上是一个标准的 RESTful 服务。以 DeepSeek 为例,其聊天接口地址为:
bash
https://api.deepseek.com/v1/chat/completions
调用它需要构造一个符合要求的 POST 请求,包含三个关键部分:
1. 请求行(Request Line)
- 方法:
POST - URL:完整接口地址
- 协议版本:HTTP/1.1(由浏览器自动处理)
2. 请求头(Headers)
必须包含两项:
Content-Type: application/json:声明请求体为 JSON 格式Authorization: Bearer <your-api-key>:身份认证令牌
3. 请求体(Body)
- 必须是字符串,不能直接传 JavaScript 对象
- 需用
JSON.stringify()序列化 - 包含模型名称、消息历史等参数
前端代码实现:用 fetch 发起请求
下面是在 main.js 中封装的调用函数:
javascript
// 从环境变量读取 API Key(Vite 支持 .env 文件)
const API_KEY = import.meta.env.VITE_DEEPSEEK_API_KEY;
const API_URL = 'https://api.deepseek.com/v1/chat/completions';
async function askDeepSeek(messages) {
const payload = {
model: 'deepseek-reasoner',
messages: messages,
max_tokens: 500
};
const response = await fetch(API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}`
},
body: JSON.stringify(payload)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data.choices[0].message.content;
}
关键点解析:
-
import.meta.env:Vite 提供的环境变量读取方式。需在项目根目录创建.env文件:iniVITE_DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxxxx注意:Vite 要求环境变量必须以
VITE_开头才能在前端暴露,这是安全机制。 -
await fetch:相比.then()链式调用,async/await语法更接近同步代码,逻辑清晰易读。 -
错误处理 :检查
response.ok可捕获 4xx/5xx 错误,避免解析失败的 JSON。
在页面中使用
在 index.html 中添加简单交互:
xml
<!DOCTYPE html>
<html>
<head>
<title>AI 助手</title>
</head>
<body>
<input type="text" id="question" placeholder="输入问题...">
<button onclick="handleAsk()">提问</button>
<div id="answer"></div>
<script type="module" src="/main.js"></script>
<script>
async function handleAsk() {
const input = document.getElementById('question');
const answerDiv = document.getElementById('answer');
try {
const response = await askDeepSeek([
{ role: 'user', content: input.value }
]);
answerDiv.textContent = response;
} catch (err) {
answerDiv.textContent = '请求失败:' + err.message;
}
}
</script>
</body>
</html>
这里通过内联 <script> 调用模块化的 askDeepSeek 函数,实现了从用户输入到 AI 回答的完整流程。
安全提醒:前端暴露 API Key 的风险
必须明确:将 API Key 写在前端代码中存在泄露风险。任何访问你网页的用户都能通过开发者工具查看该密钥。因此,这种方式仅适用于:
- 个人测试项目
- 密钥有严格用量限制
- 使用了 API 平台的域名白名单或 Referer 限制
对于生产环境,强烈建议通过自己的后端代理请求,由服务器保管密钥。
总结
通过原生 fetch API,前端可以直接与大模型服务通信,实现低延迟的智能交互。结合 Vite 的工程化能力,我们不仅能高效开发,还能通过环境变量管理敏感信息。虽然存在安全限制,但在可控场景下,这种"前端直连 LLM"的模式极大简化了 AI 应用的构建流程------从一行 HTML 到智能对话,不过百行代码的距离。