Files

第5-2课:URL与HTTP请求

一、本课目标

完成本课后,你能够:

  1. 拆解统一资源定位符(Uniform Resource Locator,URL);
  2. 解释HTTP请求行、请求头和请求体;
  3. 理解路径参数与查询参数的用途差异;
  4. 为常见操作选择GET、POST、PUT、PATCH或DELETE;
  5. 使用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为例:

  1. 浏览器看到https,知道要使用受TLS保护的HTTP;
  2. 通过DNS查询api.example.com对应的IP地址;
  3. 向该地址的443端口建立连接;
  4. 把/books/10?detail=true作为请求目标;
  5. 在连接中发送HTTP请求;
  6. 等待服务器返回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)或表单风格编码。

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请求行。

十一、代码执行顺序

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