← 代码俱乐部 · 创作者层 02 / 8
用代码呼叫 Ollama 本地跑的开源 AI 模型 —— 完全免费,不需要 API key。
ollama run qwen2.5:3b。<textarea id="q" rows="3"></textarea> <button onclick="ask()">问 AI</button> <div id="ans"></div>
<textarea id="q"> = 一个文本输入框,id 是 "q"(question)。<button onclick="ask()"> = 按钮,点击时调用 JavaScript 函数 ask()。<div id="ans"> = 一个空盒子,用来放 AI 的答案。
👉 试改:把按钮文字改成"问问 Qwen"或"开始思考"。
<script>
async function ask() {
const q = document.getElementById('q').value;async function ask() = 定义一个"异步函数"(意思是这个函数可能要"等待"某个耗时操作)。document.getElementById('q').value = 从 id="q" 的输入框里拿到用户打的内容。
💡 async/await 是什么:有些操作很慢(比如网络请求),JavaScript 用 async 和 await 来"等待"结果出现,而不卡住整个网页。
document.getElementById('ans').textContent = '思考中...';
const r = await fetch('http://localhost:11434/api/generate', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({model: 'qwen2.5:3b', prompt: q, stream: false})
});先显示"思考中..."给用户看。然后 fetch(...) 向本地 Ollama 服务(localhost:11434)发一个 HTTP 请求。method: 'POST' = 用 POST 方法(用于发送数据)。body: JSON.stringify(...) = 把我们的请求数据(模型、问题)转成 JSON 发过去。
💡 这就是"网页和 AI 通话的方式":网页用 HTTP 请求和 Ollama 聊天,就像打电话一样。
👉 试改:改 'qwen2.5:3b' 成其他模型(如果你装了的话)。
const data = await r.json();
document.getElementById('ans').textContent = data.response;
}
</script>await r.json() = 等待 Ollama 的回复,然后把它从 JSON 转成 JavaScript 对象。data.response = 从返回的数据里提出 "response" 字段(这就是 AI 生成的文本)。最后显示到 id="ans" 的盒子里。
💡 完整流程:用户输入 → fetch 发请求 → Ollama 接到并思考 → 返回 JSON → 网页解析并显示。整个循环只需 3-5 秒。
<textarea id="q" rows="3"></textarea>
<button onclick="ask()">问 AI</button>
<div id="ans"></div>
<script>
async function ask() {
const q = document.getElementById('q').value;
document.getElementById('ans').textContent = '思考中...';
const r = await fetch('http://localhost:11434/api/generate', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({model: 'qwen2.5:3b', prompt: q, stream: false})
});
const data = await r.json();
document.getElementById('ans').textContent = data.response;
}
</script>
一个更复杂的例子,演示怎么从嵌套的 JSON 数据中提取信息,并加上搜索功能:
<!DOCTYPE html>
<html>
<head><style>
body { font-family: sans-serif; padding: 20px; background: #f5f5f5; }
.search { margin: 20px 0; }
.search input { padding: 8px 12px; font-size: 14px; width: 300px; }
.post { background: white; padding: 20px; border-radius: 8px; margin: 10px 0; border-left: 4px solid #667eea; }
.post h3 { margin: 0 0 10px 0; color: #667eea; }
.meta { color: #999; font-size: 14px; }
</style></head>
<body>
<h1>文章博客</h1>
<div class="search">
<input type="text" id="search" placeholder="搜索文章标题..." />
</div>
<div id="output"></div>
<script>
let apiData = {
posts: [
{ id: 1, title: '我学会了 HTML', author: '小王', date: '2026-05-01', content: '今天我写了自己的第一个网页...' },
{ id: 2, title: 'CSS 让网页变漂亮', author: '小红', date: '2026-05-02', content: '颜色、字体、布局都可以用 CSS 控制...' },
{ id: 3, title: 'JavaScript 让网页活起来', author: '小李', date: '2026-05-03', content: '用户点一下,网页就反应。' }
]
};
function render(posts) {
let html = '';
for (let post of posts) {
html += '<div class="post">';
html += '<h3>' + post.title + '</h3>';
html += '<div class="meta">' + post.author + ' · ' + post.date + '</div>';
html += '<p>' + post.content + '</p>';
html += '</div>';
}
document.getElementById('output').innerHTML = html;
}
render(apiData.posts);
</script>
</body>
</html>
进阶:这就是"怎么从 API 取数据"的核心 —— 数据来了之后,用 for 循环遍历,然后把每一项都显示在网页上。
一个完整的聊天界面,加了更好的样式和错误处理:
<!DOCTYPE html>
<html>
<head><style>
body { font-family: sans-serif; padding: 20px; background: #f5f5f5; }
.container { max-width: 600px; margin: 0 auto; }
.chat { background: white; border-radius: 8px; padding: 20px; margin: 20px 0; height: 400px; overflow-y: auto; }
.message { margin: 12px 0; padding: 12px 15px; border-radius: 8px; word-wrap: break-word; }
.user { background: #667eea; color: white; text-align: right; margin-left: 60px; }
.ai { background: #f0f0f0; color: #333; margin-right: 60px; }
.input-area { display: flex; gap: 10px; }
input { flex: 1; padding: 12px; font-size: 14px; border: 1px solid #ddd; border-radius: 5px; }
button { padding: 12px 24px; background: #667eea; color: white; border: none; border-radius: 5px; cursor: pointer; }
button:hover { background: #764ba2; }
</style></head>
<body>
<div class="container">
<h1>和 AI 聊天</h1>
<div class="chat" id="chat">
<div class="message ai">嗨,我是你的 AI 助手。有什么问题吗?</div>
</div>
<div class="input-area">
<input type="text" id="question" placeholder="输入你的问题..." onkeypress="if(event.key==='Enter') sendMessage()" />
<button onclick="sendMessage()">发送</button>
</div>
</div>
<script>
let conversation = [];
function sendMessage() {
let question = document.getElementById('question').value.trim();
if (!question) return;
conversation.push({ role: 'user', text: question });
// 模拟 AI 回答
let answer = 'AI:' + question + ' —— 是个有趣的问题呢!';
conversation.push({ role: 'ai', text: answer });
let html = '';
for (let msg of conversation) {
let cls = msg.role === 'user' ? 'user' : 'ai';
html += '<div class="message ' + cls + '">' + msg.text + '</div>';
}
let chat = document.getElementById('chat');
chat.innerHTML = html;
chat.scrollTop = chat.scrollHeight;
document.getElementById('question').value = '';
document.getElementById('question').focus();
}
</script>
</div>
</body>
</html>
进阶:注意 scrollTop 和 scrollHeight —— 这让聊天框自动滚到底部。
"调用 AI"不是付费公司的特权。本地一行命令就能跑起来。而且断网都行。