Skip to Content
⏱ 本页预计时间
阅读 11 分钟 · 练习 60 分钟

4.1 调用第三方 API

正在检查访问权限...

这一节教你用别人已经做好的 API,就像去餐厅点菜一样简单。

🎯

学完这节你会

  • 理解什么是 API(不用记那些专业术语)
  • 会调用天气 API 显示实时天气
  • 会调用 DeepSeek API 做一个 AI 聊天功能
  • 知道怎么安全地管理 API 密钥

什么是 API?用餐厅类比理解

API 就像餐厅的服务员

你(前端):「我要一份宫保鸡丁」 → 服务员(API)把单子交给厨房 → 厨房(后端/数据库)做好了 → 服务员把菜端给你

你不用进厨房,只需要:

  1. 知道怎么点菜(调用 API)
  2. 等着接菜(接收数据)

第三方 API vs 自己写的 API

类型比喻例子
第三方 API去别人餐厅吃饭天气 API、DeepSeek API、地图 API
自己写的 API自己开餐厅你自己的数据库操作接口

这一节先学第一种 - 用别人的,最简单!


实战 1:调用天气 API

我们用免费的天气 API 来做第一个例子。

步骤 1:获取 API 密钥

  1. 访问 WeatherAPI.com 
  2. 注册免费账号
  3. 获取你的 API Key(类似 sk-a1b2c3d4e5f6...

API Key 就像你家钥匙,别告诉别人! 待会儿我们会教你怎么安全存储。

步骤 2:测试 API 调用

打开浏览器,访问这个网址(把 YOUR_API_KEY 替换成你的密钥):

https://api.weatherapi.com/v1/current.json?key=YOUR_API_KEY&q=Beijing

你应该能看到一堆 JSON 数据,类似:

什么是 JSON? JSON(JavaScript Object Notation)是一种数据格式,用来在网络上传输数据。它用大括号 {} 表示对象,方括号 [] 表示数组,冒号 : 分隔键和值。几乎所有 API 返回的数据都是 JSON 格式。

{ "location": { "name": "Beijing", "country": "China" }, "current": { "temp_c": 15.0, "condition": { "text": "Sunny" } } }

恭喜!你已经成功调用了一个真实的 API!

步骤 3:在 Next.js 项目中调用

创建一个新页面 app/weather/page.tsx

代码解读'use client' 告诉 Next.js 这是客户端组件(需要浏览器交互)。useState 是 React 的「状态钩子」,用来存储会变化的数据(城市名、天气数据、加载状态)。async/await 是处理异步操作的语法,让你可以「等待」API 返回数据。

'use client' import { useState } from 'react' export default function WeatherPage() { const [city, setCity] = useState('Beijing') const [weather, setWeather] = useState(null) const [loading, setLoading] = useState(false) const getWeather = async () => { setLoading(true) try { // 注意:这里先硬编码,下一步我们会改进 const API_KEY = 'YOUR_API_KEY' // ⚠️ 先别这样做! const res = await fetch( `https://api.weatherapi.com/v1/current.json?key=${API_KEY}&q=${city}` ) const data = await res.json() setWeather(data) } catch (error) { console.error('获取天气失败', error) } setLoading(false) } return ( <div className="p-8"> <h1 className="text-2xl font-bold mb-4">天气查询</h1> <input type="text" value={city} onChange={(e) => setCity(e.target.value)} placeholder="输入城市名" className="border p-2 mr-2" /> <button onClick={getWeather} className="bg-blue-500 text-white px-4 py-2 rounded" > 查询天气 </button> {loading && <p className="mt-4">加载中...</p>} {weather && ( <div className="mt-4 p-4 border rounded"> <h2 className="text-xl">{weather.location.name}</h2> <p>温度:{weather.current.temp_c}°C</p> <p>天气:{weather.current.condition.text}</p> </div> )} </div> ) }

步骤 4:安全管理 API 密钥 ⭐

问题:上面的代码把 API Key 直接写在代码里,这样:

  • ❌ Key 会被任何人看到(如果你的代码开源)
  • ❌ 部署到 GitHub 会泄露

正确做法:用环境变量

  1. 在项目根目录创建 .env.local 文件:
# .env.local NEXT_PUBLIC_WEATHER_API_KEY=你的真实API密钥
  1. 修改代码:
const API_KEY = process.env.NEXT_PUBLIC_WEATHER_API_KEY
  1. 确保 .env.local.gitignore 里(Next.js 默认已包含)

为什么要加 NEXT_PUBLIC_ 前缀?

Next.js 规定:

  • NEXT_PUBLIC_ 开头的变量可以在浏览器(客户端)使用
  • 没有这个前缀的只能在服务端使用

因为我们在 'use client' 组件里调用,所以需要加前缀。

步骤 5:部署时配置环境变量

如果你用 Vercel 部署:

  1. 打开项目设置 → Environment Variables
  2. 添加 NEXT_PUBLIC_WEATHER_API_KEY,值填你的 API Key
  3. 重新部署

实战 2:调用 DeepSeek API(AI 聊天)

现在我们来做一个更酷的 - AI 聊天功能!

步骤 1:获取 DeepSeek API Key

  1. 访问 DeepSeek 官网 
  2. 注册并获取 API Key
  3. 查看API 文档 

步骤 2:创建 API Route(后端接口)

为什么这次要用 API Route?

DeepSeek API Key 很敏感,不能在前端暴露! 所以我们要:

  • 前端 → 调用自己的 API Route
  • API Route → 调用 DeepSeek API(Key 在服务端,安全)

创建 app/api/chat/route.ts

什么是 API Route? Next.js 的 API Route 让你在同一个项目里写后端代码。app/api/ 文件夹里的文件会变成后端接口,比如 app/api/chat/route.ts 会变成 /api/chat 这个接口地址。前端调用它,它再调用外部 API,这样敏感信息就不会暴露给用户。

import { NextRequest, NextResponse } from 'next/server' export async function POST(request: NextRequest) { try { const { message } = await request.json() // 调用 DeepSeek API const response = await fetch('https://api.deepseek.com/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${process.env.DEEPSEEK_API_KEY}` // 服务端环境变量,不需要 NEXT_PUBLIC_ }, body: JSON.stringify({ model: 'deepseek-chat', messages: [ { role: 'user', content: message } ] }) }) const data = await response.json() return NextResponse.json({ reply: data.choices[0].message.content }) } catch (error) { return NextResponse.json( { error: '请求失败' }, { status: 500 } ) } }

步骤 3:创建前端页面

创建 app/chat/page.tsx

'use client' import { useState } from 'react' export default function ChatPage() { const [messages, setMessages] = useState([]) const [input, setInput] = useState('') const [loading, setLoading] = useState(false) const sendMessage = async () => { if (!input.trim()) return const userMessage = { role: 'user', content: input } setMessages(prev => [...prev, userMessage]) setInput('') setLoading(true) try { // 调用自己的 API Route const res = await fetch('/api/chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: input }) }) const data = await res.json() setMessages(prev => [...prev, { role: 'assistant', content: data.reply }]) } catch (error) { console.error('发送失败', error) } setLoading(false) } return ( <div className="max-w-2xl mx-auto p-8"> <h1 className="text-2xl font-bold mb-4">AI 聊天助手</h1> <div className="border rounded p-4 h-96 overflow-y-auto mb-4"> {messages.map((msg, i) => ( <div key={i} className={`mb-2 ${msg.role === 'user' ? 'text-right' : 'text-left'}`}> <span className={`inline-block p-2 rounded ${ msg.role === 'user' ? 'bg-blue-500 text-white' : 'bg-gray-200' }`}> {msg.content} </span> </div> ))} {loading && <p className="text-gray-500">AI 正在思考...</p>} </div> <div className="flex gap-2"> <input type="text" value={input} onChange={(e) => setInput(e.target.value)} onKeyPress={(e) => e.key === 'Enter' && sendMessage()} placeholder="输入消息..." className="flex-1 border p-2 rounded" /> <button onClick={sendMessage} disabled={loading} className="bg-blue-500 text-white px-4 py-2 rounded disabled:opacity-50" > 发送 </button> </div> </div> ) }

步骤 4:配置环境变量

.env.local 添加:

DEEPSEEK_API_KEY=你的DeepSeek密钥

注意这次不需要 NEXT_PUBLIC_ 前缀,因为只在服务端使用!


错误处理技巧

调用 API 时经常会出问题,学会处理错误很重要:

常见错误和解决方法

  1. 401 Unauthorized - API Key 错误

    检查 .env.local 里的 Key 是否正确
  2. 429 Too Many Requests - 请求太频繁

    等几分钟再试,或升级 API 套餐
  3. Network Error - 网络问题

    检查网络连接,或 API 服务器是否正常
  4. CORS Error - 跨域问题

    用 API Route 做中转(就像 DeepSeek 例子)

什么是跨域(CORS)? 浏览器出于安全考虑,默认禁止网页向不同域名发请求。比如你的网站是 example.com,直接调用 api.deepseek.com 就会被拦截。解决方法是用自己的后端做「中转站」:前端 → 自己的 API Route → 第三方 API。

推荐的错误处理模板

try { const res = await fetch(apiUrl) if (!res.ok) { throw new Error(`HTTP ${res.status}: ${res.statusText}`) } const data = await res.json() return data } catch (error) { console.error('API 调用失败:', error) // 给用户友好的提示 alert('请求失败,请稍后重试') }

环境变量管理总结

记住这个规则

使用场景变量名格式存储位置能否在客户端用
客户端调用 APINEXT_PUBLIC_XXX.env.local✅ 能
服务端调用 APIXXX(不加前缀).env.local❌ 不能

最佳实践

  • ✅ 敏感 Key(DeepSeek):用 API Route 中转
  • ✅ 公开 Key(地图 API):可以直接用 NEXT_PUBLIC_
  • ✅ 永远不要把 .env.local 提交到 Git
  • ✅ 部署时记得配置 Vercel 环境变量

快速实践建议

从最简单的开始,不要一次做太复杂:

Day 1: 天气 API

复制上面的天气代码,跑通

Day 2: 环境变量

学会用 .env.local 管理密钥

Day 3: DeepSeek API

做一个简单的 AI 聊天

Day 4: 加功能

给天气 App 加个城市列表,或给聊天加个历史记录

新手常见卡点

  1. 忘记重启开发服务器 修改 .env.local 后要重启 pnpm run dev

  2. 环境变量拼写错误 NEXT_PUBLIC_WEATHER_API_KEY 少个字母就找不到

  3. 混淆客户端和服务端 客户端组件(‘use client’)只能用 NEXT_PUBLIC_ 变量


下一节4.2 数据库与 CRUD 操作 - 学会存储和管理自己的数据

学习进度0%
0/60 篇已完成
Last updated on