Files
PythonLearn/05_web基础/5_2_URL与HTTP请求/README.md
T

190 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 第5-2课:URL与HTTP请求
## 一、本课目标
完成本课后,你能够:
1. 拆解统一资源定位符(Uniform Resource Locator,URL);
2. 解释HTTP请求行、请求头和请求体;
3. 理解路径参数与查询参数的用途差异;
4. 为常见操作选择GET、POST、PUT、PATCH或DELETE;
5. 使用Python标准库安全编码查询参数。
## 二、前置知识
- 已理解客户端与服务器;
- Python字典、函数和字符串;
- 不要求记忆HTTP报文的所有字段。
## 三、URL的组成
示例:
```text
https://api.example.com:443/books/10?detail=true#summary
```
| 部分 | 示例 | 作用 |
|---|---|---|
| 协议 | `https` | 约定通信方式 |
| 主机 | `api.example.com` | 定位服务器 |
| 端口 | `443` | 定位服务器中的服务 |
| 路径 | `/books/10` | 定位资源 |
| 查询字符串 | `detail=true` | 提供筛选或选项 |
| 片段 | `summary` | 通常只供客户端定位页面位置,不发送给服务器 |
HTTPS是经过传输层安全协议(Transport Layer Security,TLS)保护的HTTP。它保护传输过程,但不能自动修复错误的业务权限。
浏览器真正访问时还会涉及以下概念:
- 域名(Domain Name):便于人记忆的服务器名称,例如`api.example.com`;
- IP地址(Internet Protocol Address):网络用于定位设备或服务入口的地址;
- 域名系统(Domain Name System,DNS):把域名查询为可用于连接的IP地址;
- 端口(Port):同一台计算机上用于区分不同网络服务的编号。
可以把IP地址理解成办公楼地址,把端口理解成楼内具体窗口。这个类比不代表端口是物理接口,它只是操作系统管理网络连接时使用的数字。
HTTP默认端口通常是80,HTTPS默认端口通常是443。使用默认端口时,URL可以省略端口;使用开发服务器的8000等端口时通常需要明确写出。
## 四、浏览器如何根据URL定位请求目标
以`https://api.example.com:443/books/10?detail=true`为例:
1. 浏览器看到`https`,知道要使用受TLS保护的HTTP;
2. 通过DNS查询`api.example.com`对应的IP地址;
3. 向该地址的443端口建立连接;
4. 把`/books/10?detail=true`作为请求目标;
5. 在连接中发送HTTP请求;
6. 等待服务器返回HTTP响应。
实际网络还涉及缓存、代理、网关和连接复用。本阶段只建立主干认识,不展开网络工程细节。
## 五、HTTP请求结构
```http
POST /books HTTP/1.1
Host: localhost:8000
Content-Type: application/json
{"title": "Python入门"}
```
- 请求行:请求方法、请求目标和HTTP版本;
- 请求头:描述内容类型、认证信息和客户端能力;
- 空行:分隔头部与请求体;
- 请求体:提交给服务器的数据,GET通常不依赖请求体。
逐行阅读这份请求:
1. `POST /books HTTP/1.1`表示使用POST方法访问`/books`;
2. `Host`说明目标主机和端口;
3. `Content-Type`说明请求体是JSON;
4. 空行表示请求头结束;
5. 最后一行JSON是提交给服务器的数据。
HTTP报文在网络中最终按字节传输。这里用文本形式展示,是为了让结构更容易阅读。
## 六、常用请求方法
| 方法 | 常见含义 | 图书示例 |
|---|---|---|
| GET | 查询 | 查询图书 |
| POST | 创建或触发处理 | 新增图书 |
| PUT | 整体替换 | 替换图书全部可修改信息 |
| PATCH | 局部修改 | 只修改价格 |
| DELETE | 删除 | 删除图书 |
方法表达意图,最终行为仍由服务器代码决定。GET应当是安全方法,即正常调用不应修改业务数据;重复执行PUT或DELETE通常应具有幂等性,即最终效果与执行一次相同。
安全和幂等是HTTP语义,不等同于权限安全:
- “GET是安全方法”表示它不应改变业务状态;
- “DELETE通常幂等”表示重复删除后最终仍是资源不存在;
- 它们都不表示接口无需登录或权限控制。
## 七、路径参数与查询参数
- `/books/10`中的`10`通常是路径参数,用于标识某一本书;
- `/books?keyword=Python&page=2`中的值是查询参数,用于筛选、排序或分页。
请求体通常承载新增或修改时的结构化数据,例如书名、价格和作者。不要把大量结构化内容全部塞进URL。
## 八、URL编码
URL中的空格、中文、`&`和`=`可能与URL结构规则冲突,因此需要百分号编码(Percent-encoding)或表单风格编码。
```python
urlencode({"keyword": "Python Web", "page": 1})
```
结果中的空格可能显示为`+`:
```text
keyword=Python+Web&page=1
```
客户端负责编码,服务器负责解码。不要先手工替换一次,再交给工具重复编码。
## 九、完整示例
`url_request_example.py`使用`urlsplit()`拆分URL,使用`parse_qs()`读取查询参数,使用`urlencode()`处理空格等特殊字符。
## 十、运行方法
```powershell
cd D:\Code\Python\05_web基础\5_2_URL与HTTP请求
python url_request_example.py
```
关键输出包括协议、主机、端口、路径、查询参数,以及编码后的GET请求行。
## 十一、代码执行顺序
1. `main()`准备一条完整URL;
2. `parse_url()`使用`urlsplit()`拆分结构;
3. `parse_qs()`把查询字符串转换为字典;
4. 程序分别输出协议、主机、端口、路径和查询参数;
5. `build_request_target()`使用`urlencode()`编码参数;
6. 程序输出一条简化请求行和请求头。
`api.example.com`是教学示例域名,程序只解析字符串,不会访问该网站。
## 十二、常见错误
### 12.1 手工拼接查询字符串
空格、中文、`&`和`=`具有特殊含义,应交给`urlencode()`等工具编码。
### 12.2 用POST处理所有操作
程序可能运行,但接口意图模糊,缓存、重试、权限和文档也更难设计。
### 12.3 在URL中传密码
URL容易进入浏览历史和日志。密码及令牌不应放入查询字符串。
### 12.4 混淆域名、IP和端口
域名需要经过DNS解析,IP用于网络定位,端口用于区分服务。它们有关联,但不是同一个值。
### 12.5 认为HTTPS代表接口一定可信
HTTPS主要保护传输过程。客户端仍要确认访问的域名,服务器仍要进行身份认证、权限和输入校验。
## 十三、课堂练习
打开`practice.py`,完成URL解析和请求方法选择练习。
## 十四、本课小结
URL回答“向哪里请求”,HTTP方法回答“想做什么”,请求头描述消息,请求体携带提交的数据。
## 十五、验收标准
- 能拆解完整URL;
- 能解释域名、DNS、IP和端口的基本关系;
- 能解释HTTP请求的主要部分;
- 能区分路径参数和查询参数;
- 能为常见增删改查选择请求方法;
- 示例运行结果符合预期。