第5-2课:URL与HTTP请求
一、本课目标
完成本课后,你能够:
- 拆解统一资源定位符(Uniform Resource Locator,URL);
- 解释HTTP请求行、请求头和请求体;
- 理解路径参数与查询参数的用途差异;
- 为常见操作选择GET、POST、PUT、PATCH或DELETE;
- 使用Python标准库安全编码查询参数。
二、前置知识
- 已理解客户端与服务器;
- Python字典、函数和字符串;
- 不要求记忆HTTP报文的所有字段。
三、URL的组成
示例:
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为例:
- 浏览器看到
https,知道要使用受TLS保护的HTTP; - 通过DNS查询
api.example.com对应的IP地址; - 向该地址的443端口建立连接;
- 把
/books/10?detail=true作为请求目标; - 在连接中发送HTTP请求;
- 等待服务器返回HTTP响应。
实际网络还涉及缓存、代理、网关和连接复用。本阶段只建立主干认识,不展开网络工程细节。
五、HTTP请求结构
POST /books HTTP/1.1
Host: localhost:8000
Content-Type: application/json
{"title": "Python入门"}
- 请求行:请求方法、请求目标和HTTP版本;
- 请求头:描述内容类型、认证信息和客户端能力;
- 空行:分隔头部与请求体;
- 请求体:提交给服务器的数据,GET通常不依赖请求体。
逐行阅读这份请求:
POST /books HTTP/1.1表示使用POST方法访问/books;Host说明目标主机和端口;Content-Type说明请求体是JSON;- 空行表示请求头结束;
- 最后一行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)或表单风格编码。
urlencode({"keyword": "Python Web", "page": 1})
结果中的空格可能显示为+:
keyword=Python+Web&page=1
客户端负责编码,服务器负责解码。不要先手工替换一次,再交给工具重复编码。
九、完整示例
url_request_example.py使用urlsplit()拆分URL,使用parse_qs()读取查询参数,使用urlencode()处理空格等特殊字符。
十、运行方法
cd D:\Code\Python\05_web基础\5_2_URL与HTTP请求
python url_request_example.py
关键输出包括协议、主机、端口、路径、查询参数,以及编码后的GET请求行。
十一、代码执行顺序
main()准备一条完整URL;parse_url()使用urlsplit()拆分结构;parse_qs()把查询字符串转换为字典;- 程序分别输出协议、主机、端口、路径和查询参数;
build_request_target()使用urlencode()编码参数;- 程序输出一条简化请求行和请求头。
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请求的主要部分;
- 能区分路径参数和查询参数;
- 能为常见增删改查选择请求方法;
- 示例运行结果符合预期。