跳到主要内容

HTTP 请求与 API:让程序上网冲浪

什么是 API?

你去餐厅吃饭,不会跑到厨房自己炒菜。你做的是:看菜单,选好菜,告诉服务员,然后服务员把菜从厨房端给你。

API(Application Programming Interface)就是程序世界的"菜单 + 服务员"。

  • 菜单 = API 文档(告诉你有什么功能、怎么用)
  • 点菜 = 发送请求(告诉服务器你想要什么)
  • 上菜 = 返回响应(服务器把数据端给你)

你不需要知道"厨房"里是怎么做的,只要按照菜单点菜就行。这就是 API 的精髓——封装复杂性,暴露简单接口

HTTP 请求基础

互联网上绝大多数 API 都基于 HTTP 协议。你每次打开网页,浏览器其实就在不停地发 HTTP 请求。

最常用的两种请求方法:

方法用途生活比喻
GET获取数据去图书馆借书(我要看看有什么)
POST提交数据去邮局寄快递(我要发送东西)

还有 PUT(修改数据)、DELETE(删除数据)等,但 GET 和 POST 覆盖了 80% 的场景。

发送 GET 请求

加载代码编辑器中……
Python (requests)JavaScript (fetch)
安装pip install requests内置(Node 18+ / 浏览器)
发请求requests.get(url)await fetch(url)
状态码response.status_coderesponse.status
解析 JSONresponse.json()await response.json()
查询参数params={"k": "v"}URLSearchParams 拼到 URL

Python 的 requests 库号称"HTTP for Humans"(人类用的 HTTP 库),API 设计极其简洁直观。JS 的 fetch 原生支持,但需要搭配 async/await 使用。

发送 POST 请求

GET 是"拿数据",POST 是"送数据"。比如注册账号、提交表单、发消息等场景:

加载代码编辑器中……
PythonJavaScript
POST 请求requests.post(url, json=data)fetch(url, { method: "POST", body: JSON.stringify(data) })
设置请求头headers={"K": "V"}headers: {"K": "V"}
发送 JSONjson=data(自动序列化)body: JSON.stringify(data)(手动序列化)

注意 Python 的 requests.post(url, json=data) 有多方便——传 json= 参数会自动把字典序列化成 JSON 字符串,还自动设置 Content-Type 请求头。JS 的 fetch 就没这么贴心了,得自己来。

HTTP 状态码

每次服务器回应你,都会带一个"状态码"告诉你结果如何:

状态码含义生活比喻
200OK,成功"菜来了,请享用"
201Created,创建成功"您的订单已提交"
400Bad Request,请求有误"你点的菜菜单上没有"
401Unauthorized,未认证"请先出示会员卡"
403Forbidden,无权限"VIP 包间不对外开放"
404Not Found,找不到"这道菜已经下架了"
500Server Error,服务器挂了"厨房着火了,暂停营业"
加载代码编辑器中……

Python 的 requests 不会因为 4xx/5xx 状态码自动抛异常,需要手动检查或调用 response.raise_for_status()。JS 的 fetch 也一样——它只在网络错误时才会 reject,4xx/5xx 只是 response.okfalse。这是新手常踩的坑。

REST API 入门

现代 Web API 大多遵循 REST(Representational State Transfer)风格。简单说就是用 HTTP 方法 + URL 路径来表达操作:

操作HTTP 方法URL 示例含义
获取所有用户GET/api/users列出用户
获取单个用户GET/api/users/123查看 ID=123 的用户
创建用户POST/api/users新增一个用户
修改用户PUT/api/users/123更新 ID=123 的用户
删除用户DELETE/api/users/123删除 ID=123 的用户

这种设计就像图书馆的管理规则:

  • GET = 查书(只看不碰)
  • POST = 捐书(增加新书)
  • PUT = 换书(替换旧版)
  • DELETE = 撤书(移除下架)

URL 路径表示"资源",HTTP 方法表示"对这个资源做什么"。一目了然。

加载代码编辑器中……
问问 AI

问 AI:"RESTful API 的设计理念是什么?为什么要把 URL 当作'资源',用 HTTP 方法表示'动作'?跟传统的 RPC 风格有什么区别?"

这个问题会帮你理解 REST 不只是一种写法,更是一种设计哲学。互联网上大多数你能接触到的 API(微信开放平台、GitHub API、各种云服务)都遵循这个理念。

异步请求:Python vs JS 的哲学差异

在网络请求这个领域,两种语言的"性格差异"体现得淋漓尽致:

  • Python:默认同步(一步一步来),想异步要额外努力
  • JavaScript:天生异步(不等结果就继续),想同步反而麻烦
加载代码编辑器中……

JS 的 Promise.all() 可以同时发起多个请求,总耗时取决于最慢的那个。Python 同步模式下只能一个接一个,总耗时是所有请求之和。这就是为什么 Node.js 在处理大量 I/O 操作(比如 Web 服务器同时服务千百个用户)时表现出色。

踩坑提醒

CORS——前端开发者的噩梦

如果你在浏览器里用 fetch 调用别人的 API,很可能会看到这个错误:

Access to fetch at 'https://api.xxx.com' from origin 'http://localhost:3000'
has been blocked by CORS policy

这就是 CORS(跨域资源共享)。浏览器出于安全考虑,默认不允许网页向其他域名发请求。

解决方案:

  1. 后端配置 CORS 头(Access-Control-Allow-Origin
  2. 用后端做代理转发
  3. 开发时用代理工具

注意:Python 的 requests 和 Node.js 脚本不受 CORS 限制,因为 CORS 是浏览器的安全策略,不是 HTTP 协议本身的限制。所以同样的代码在 Node.js 里跑没问题,放到浏览器就报错——这不是 bug,是"feature"。

实战:调用公共 API

互联网上有很多免费的公共 API 可以练手。来看几个好玩的:

加载代码编辑器中……
🏋️AI 练习

毕业项目时间!选一个公共 API,写一个有用的小工具:

推荐的免费 API:

  • GitHub API:https://api.github.com(无需认证即可访问公开数据)
  • JSONPlaceholder:https://jsonplaceholder.typicode.com(模拟 REST API,适合练手)
  • Open Meteo 天气:https://api.open-meteo.com(免费天气数据)

挑战任务:

  1. 选一个 API,用 Python 的 requests 获取数据
  2. 用同样的 API,用 JS 的 fetch 获取数据
  3. 把获取到的数据格式化输出
  4. 把结果保存到 JSON 文件(结合上一节的知识)

比如:写一个"GitHub 仓库探索器",输入一个关键词,搜索相关仓库并显示名称、星标数和描述,然后把结果保存到本地 JSON 文件。

这个练习综合了本章学到的所有知识——文件、JSON、HTTP。完成它,你就真正学会了"让程序与世界对话"!

小结

概念PythonJavaScript
HTTP 库requests(需安装)fetch(内置)
GET 请求requests.get(url)await fetch(url)
POST 请求requests.post(url, json=data)await fetch(url, {method: "POST", body: ...})
状态码response.status_coderesponse.status
解析 JSONresponse.json()await response.json()
请求头headers={...}headers: {...}
超时设置timeout=5AbortSignal.timeout(5000)
同步/异步默认同步天生异步

一句话总结:Python 的 requests 简单直白——发请求、拿结果、处理数据,三步搞定。JS 的 fetch 需要搭配 async/await,写起来稍微啰嗦,但天生支持并发,在处理大量网络请求时效率更高。两种语言各有所长,学会了都能让你的程序从"单机游戏"变成"联网游戏"。