190 lines
6.7 KiB
Markdown
190 lines
6.7 KiB
Markdown
# 第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请求的主要部分;
|
||
- 能区分路径参数和查询参数;
|
||
- 能为常见增删改查选择请求方法;
|
||
- 示例运行结果符合预期。
|