想拥有一个属于自己的、类似 ChatGPT 的 AI 聊天网页吗? 本教程将带你使用最基础的 Node.js 和 HTML,不依赖复杂的框架(如 Vue/React 或 Express),从零开始搭建一个支持打字机流式回复的聊天应用。
适合人群:具备基础编程知识,想了解 AI 应用底层原理的开发者或爱好者。
🛠️ 第一步:环境准备与初始化
首先,确保你的电脑上已经安装了 Node.js (建议 v18 或更高版本)。
-
创建项目文件夹 在你的电脑上新建一个文件夹,例如
my-ai-chat,然后在终端(命令行)中进入该目录:mkdir my-ai-chat cd my-ai-chat -
初始化项目 运行以下命令生成
package.json配置文件:npm init -y -
修改项目类型 打开生成的
package.json文件,在里面添加一行"type": "module", 这样我们就可以使用现代的import语法了。{ "name": "my-ai-chat", "version": "1.0.0", "type": "module", // <--- 添加这一行 ... } -
安装必要依赖 我们需要两个库:
openai(用于连接 AI 模型) 和dotenv(用于安全管理密钥)。npm install openai dotenv
🔑 第二步:准备 API 密钥
本项目使用 DeepSeek(深度求索)的大模型能力。
👉 指引:请前往 DeepSeek 开放平台 注册账号并创建 API Key 即可。
拿到以 sk- 开头的密钥后,在项目根目录下创建一个名为 .env 的文件,内容如下:
DEEPSEEK_API_KEY=你的密钥粘贴在这里
PORT=3000
🖥️ 第三步:编写后端 (Server)
我们将创建一个简单的 HTTP 服务器,它负责接收你的问题,转发给 DeepSeek,然后把 AI 的回答一点一点“流”回给浏览器。
创建文件夹 src,并在其中新建文件 server.js,填入以下代码:
// src/server.js
import http from "node:http";
import OpenAI from "openai";
import dotenv from "dotenv";
import { readFile } from "node:fs/promises";
// 读取 .env 中的配置
dotenv.config();
// 初始化 AI 客户端
const client = new OpenAI({
apiKey: process.env.DEEPSEEK_API_KEY,
baseURL: "https://api.deepseek.com/v1", // DeepSeek 的 API 地址
});
// 辅助函数:发送流式数据
function sendJson(res, type, content) {
res.write(JSON.stringify({ type, content }) + "\n");
}
const server = http.createServer(async (req, res) => {
const url = new URL(req.url, `http://${req.headers.host}`);
// 1. 提供前端页面
if (req.method === "GET" && (url.pathname === "/" || url.pathname === "/chat.html")) {
try {
const html = await readFile(new URL("./chat.html", import.meta.url));
res.writeHead(200, { "Content-Type": "text/html" });
res.end(html);
} catch {
res.statusCode = 404;
res.end("Not Found");
}
return;
}
// 2. 处理聊天接口
if (req.method === "POST" && url.pathname === "/api/chat") {
// 读取用户发送的消息
let body = "";
for await (const chunk of req) body += chunk;
const { message } = JSON.parse(body || "{}");
// 设置响应头:告诉浏览器我们要发送流式数据
res.writeHead(200, {
"Content-Type": "application/json",
"Connection": "keep-alive",
"Cache-Control": "no-cache",
});
try {
// 调用 DeepSeek API
const stream = await client.chat.completions.create({
model: "deepseek-chat",
messages: [
{ role: "system", content: "你是一个有用的AI助手。" },
{ role: "user", content: message },
],
stream: true, // 开启流式模式
});
// 实时接收 AI 的回答并转发给前端
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content || "";
if (content) sendJson(res, "message", content);
}
} catch (error) {
console.error(error);
sendJson(res, "error", "出错了,请稍后再试");
} finally {
sendJson(res, "done", "[DONE]");
res.end();
}
return;
}
res.statusCode = 404;
res.end("Not Found");
});
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
console.log(`Server is running at http://localhost:${PORT}`);
});
🎨 第四步:编写前端 (UI)
现在我们需要一个漂亮的界面来聊天。在 src 文件夹下新建 chat.html。
这是一个包含 HTML、CSS 和 JS 的完整单文件:
<!-- src/chat.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的 AI 助手</title>
<style>
/* 简单的样式美化 */
body { margin: 0; font-family: sans-serif; background: #f0f2f5; display: flex; justify-content: center; height: 100vh; }
.container { width: 100%; max-width: 800px; background: white; display: flex; flex-direction: column; box-shadow: 0 0 10px rgba(0,0,0,0.1); }
.chat-box { flex: 1; padding: 20px; overflow-y: auto; display: flex; flex-direction: column; gap: 15px; }
.msg { max-width: 80%; padding: 10px 15px; border-radius: 10px; line-height: 1.5; word-wrap: break-word; }
.msg.user { align-self: flex-end; background: #007bff; color: white; }
.msg.assistant { align-self: flex-start; background: #e9ecef; color: #333; }
.input-area { padding: 20px; border-top: 1px solid #eee; display: flex; gap: 10px; }
textarea { flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 5px; resize: none; height: 50px; }
button { padding: 0 20px; background: #007bff; color: white; border: none; border-radius: 5px; cursor: pointer; }
button:disabled { background: #ccc; }
</style>
</head>
<body>
<div class="container">
<div class="chat-box" id="chat">
<div class="msg assistant">你好!我是你的 AI 助手,有什么可以帮你的吗?</div>
</div>
<div class="input-area">
<textarea id="input" placeholder="输入你的问题..."></textarea>
<button id="send">发送</button>
</div>
</div>
<script>
const chatEl = document.getElementById('chat');
const inputEl = document.getElementById('input');
const sendBtn = document.getElementById('send');
// 添加消息到屏幕
function addMsg(role, text) {
const div = document.createElement('div');
div.className = `msg ${role}`;
div.textContent = text;
chatEl.appendChild(div);
chatEl.scrollTop = chatEl.scrollHeight;
return div;
}
// 发送消息的主逻辑
async function sendMessage() {
const text = inputEl.value.trim();
if (!text) return;
// 1. 显示用户消息
addMsg('user', text);
inputEl.value = '';
sendBtn.disabled = true;
// 2. 创建 AI 回复的占位气泡
const aiMsgEl = addMsg('assistant', '');
try {
// 3. 发起请求
const res = await fetch('/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: text })
});
// 4. 读取流式响应
const reader = res.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { value, done } = await reader.read();
if (done) break;
// 解码数据块
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split('\n');
buffer = lines.pop(); // 保留未完整的行
for (const line of lines) {
if (!line.trim()) continue;
try {
const json = JSON.parse(line);
if (json.type === 'message') {
// 🌟 关键:将新收到的文字追加到气泡中
aiMsgEl.textContent += json.content;
chatEl.scrollTop = chatEl.scrollHeight;
}
} catch (e) { console.error(e); }
}
}
} catch (err) {
aiMsgEl.textContent += " [请求失败]";
} finally {
sendBtn.disabled = false;
}
}
sendBtn.addEventListener('click', sendMessage);
</script>
</body>
</html>
🚀 第五步:启动与体验
一切就绪!现在让我们把服务跑起来。
-
启动服务 在终端中运行:
node src/server.js如果你看到
Server is running at http://localhost:3000,说明启动成功了! -
打开浏览器 访问 http://localhost:3000。
-
开始聊天 在输入框输入“讲个笑话”,你会看到 AI 的回复是一个字一个字蹦出来的,这就是流式响应的魅力!
🎉 总结
恭喜你!你已经成功搭建了一个现代化的 AI 聊天应用。
在这个过程中,你学会了:
- 使用 Node.js 原生模块 搭建 Web 服务器。
- 调用 OpenAI SDK (适配 DeepSeek) 进行 AI 对话。
- 实现后端到前端的 流式数据传输 (Streaming)。
- 前端如何解析流数据并实时渲染。
这正是目前市面上大多数 AI 产品(如 ChatGPT)的核心实现原理。快去向大家展示你的成果吧!