# M2.2 HTTP 与 API 基础

> 目标：搞懂"请求-响应"模型、REST/JSON、鉴权，能看懂一次网络请求。

## 1. 请求 / 响应模型

你每次打开网页、调一次接口，都是一次**请求-响应**：

```
客户端（你的程序/浏览器）
   │  请求(Request)：方法 + URL + 头 + 体
   ▼
服务器
   │  响应(Response)：状态码 + 头 + 体(JSON/HTML)
   ▼
客户端收到结果
```

常用方法：
- `GET`：取数据（查天气）
- `POST`：提交数据（登录、发消息）
- `PUT/PATCH`：改数据
- `DELETE`：删数据

## 2. REST 风格、JSON 格式

**REST**：用 URL 表示"资源"，用方法表示"动作"。
```
GET    /users/123      # 查 id=123 的用户
POST   /users          # 新建用户
DELETE /users/123      # 删除该用户
```

**JSON**：API 之间交换数据的标准格式（长得像 Python 字典）。

```json
{
  "name": "瑞冬",
  "age": 30,
  "tags": ["AI", "Agent"]
}
```

## 3. 鉴权：API Key 怎么用、别泄露

很多 API 需要钥匙（API Key）证明"你有权用"。

```python
import requests

# 方式一：放在请求头（最常见）
headers = {"Authorization": "Bearer sk-xxxx你的密钥"}
resp = requests.get("https://api.example.com/me", headers=headers)

# 方式二：放在参数（不推荐，容易泄露在日志）
# requests.get("https://api.example.com/me?api_key=sk-xxx")
```

**安全红线**：
- 密钥**绝不**写进代码提交到 Git
- 用环境变量 / `.env` 文件（且 `.env` 加进 `.gitignore`）
- 泄露了立刻去后台"吊销"重发

```python
import os
# 正确做法：从环境变量读
API_KEY = os.getenv("MY_API_KEY")
headers = {"Authorization": f"Bearer {API_KEY}"}
```

## 4. 用浏览器/工具看网络请求

- **浏览器**：F12 → Network 标签 → 刷新页面，点任意请求看 Headers/Response。
- **curl**：`curl -i https://api.github.com` 看响应头和状态码。
- **Postman / Apifox**：图形化发请求，调试 API 神器。

```bash
# 用 curl 看一个接口的原始返回
curl -s https://api.github.com/repos/python/cpython | head -c 300
```

## 动手练习

1. 打开浏览器 F12，访问一个网站，在 Network 里找一条 `GET` 请求，看它的状态码（200? 301? 404?）。
2. 用 curl 调 `https://ipapi.co/json/`，看返回的 JSON 里有哪些字段。
3. 把你的 API Key 写进 `.env` 文件（内容 `MY_API_KEY=xxx`），再用 `os.getenv` 读出来打印（确认本地能跑）。

## 自测

1. GET 和 POST 的核心区别是什么？
2. 为什么 API Key 放 URL 参数比放 Header 危险？
3. 状态码 404 / 500 / 200 分别意味着什么？
