方法就是请求行第一个词。HTTP/1.1 定了八个,日常只用五个。语义靠约定,协议只认名字。
上一节看第二段(目标),这一节看第一段(方法)。 方法是「我想干什么」,也是缓存、重试、幂等判断的唯一依据。
一、八个方法各管什么
| 方法 | 语义 | 幂等 | 有正文 |
|---|---|---|---|
| GET | 取资源 | 是 | 否 |
| HEAD | 只取首部 | 是 | 否 |
| POST | 提交处理 | 否 | 是 |
| PUT | 整体替换 | 是 | 是 |
| PATCH | 局部更新 | 否 | 是 |
| DELETE | 删除 | 是 | 否 |
| OPTIONS | 问支持什么 | 是 | 否 |
| TRACE | 回显请求 | 是 | 否 |
| 「幂等」指执行一次和执行多次效果相同。 | |||
| 它不是「没有副作用」——DELETE 有副作用(东西没了),但删两次和删一次结果一样,所以幂等。 | |||
| PUT 幂等而 POST 不幂等,是两者最本质的区别:PUT 的意思是「把资源变成这样」,重复执行结果不变; | |||
| POST 的意思是「请处理这件事」,重复执行可能下单两次。 |
二、协议不强制语义
Demo 里八种方法都发出去了,服务端全部照收——因为它只认方法名,不校验语义。
你发 DELETE 它也可以当 GET 处理。
所以安全边界必须在应用层实现:方法名不是权限,真正的校验是认证与授权(第八章)。
这一点在渗透测试里天天被利用。
TRACE 几乎是历史遗留:它会原样回显请求(包括 Cookie),是典型的 XST 攻击载体,
主流服务器与浏览器默认关闭。书里还列着它,但 2026 年的现实是基本见不到。
三、HEAD 和 OPTIONS 的实际用途
HEAD 拿首部不拿正文,用来检查「资源还在不在、多大、什么时候改的」,省掉整个正文的传输。
下载工具判断断点续传时就用它。
OPTIONS 拿 Allow 首部,知道这个地址支持哪些方法。
更重要的是 CORS 预检:浏览器跨域发非简单请求前,会先发一个 OPTIONS 问「你允不允许」,
服务端必须回一堆 Access-Control-* 首部。
顺带说一句:PATCH 是 2010 年才补进标准的(RFC 5789),比其它七个晚很多,所以老书里没有。
四、动手 Demo:八种方法真发一遍
逐个构造请求发出去,服务端把收到的请求行和正文长度记下来。 HEAD 与 OPTIONS 用专门的响应形态,其余回 200。
methods = [(u'GET', b'', u'取资源'),
(u'POST', b'a=1', u'提交数据,非幂等'),
(u'PUT', b'a=1', u'整体替换,幂等'),
(u'DELETE', b'', u'删除,幂等'),
(u'HEAD', b'', u'只要首部不要正文'),
(u'OPTIONS', b'', u'问支持哪些方法'),
(u'PATCH', b'a=1', u'局部更新,非幂等'),
(u'TRACE', b'', u'回显请求,几乎全被禁用')]
实跑输出:
--------------------------------------------------------------------
八种方法真发一遍,看服务端收到什么
--------------------------------------------------------------------
GET GET /res HTTP/1.1(正文 0 字节)
含义 取资源
POST POST /res HTTP/1.1(正文 3 字节)
含义 提交数据,非幂等
PUT PUT /res HTTP/1.1(正文 3 字节)
含义 整体替换,幂等
DELETE DELETE /res HTTP/1.1(正文 0 字节)
含义 删除,幂等
HEAD HEAD /res HTTP/1.1(正文 0 字节)
含义 只要首部不要正文
OPTIONS OPTIONS /res HTTP/1.1(正文 0 字节)
含义 问支持哪些方法
PATCH PATCH /res HTTP/1.1(正文 3 字节)
含义 局部更新,非幂等
TRACE TRACE /res HTTP/1.1(正文 0 字节)
含义 回显请求,几乎全被禁用
实发成功 8 种
HEAD 的响应有首部、没正文;OPTIONS 的响应含 Allow 首部——这两处最容易漏。
服务端只认方法名,不认语义:你发 DELETE 它也可以当 GET 处理,
语义约束在应用层,协议本身不强制。
实发成功 8 种,其中 POST/PUT/PATCH 三行的正文是 3 字节(a=1),
其余 0 字节——有正文的只有这三个(PATCH 也是)。
HEAD 的响应有首部没正文,OPTIONS 的响应带 Allow 首部。
这两处是最容易写错的地方:很多人用 Content-Length 判断响应是否完整,
遇到 HEAD 会一直等一个永远不来的正文。
服务端全部照收,说明方法名不构成任何安全边界。
30 秒实验
- 把 DELETE 换成
delete(小写),看服务端收到的是不是原样(是)。 想想真实服务器怎么处理——多数会 405 或 400。 - 给 GET 加上正文,看服务端收不收(收,但语义未定义,很多代理会丢掉)。
- 用
OPTIONS *问整台服务器,看响应里Allow怎么写。
常见误区
- 「GET 和 POST 的唯一区别是有没有正文」——真正的区别是语义与幂等性, GET 也能带正文(虽然不推荐)。
- 「POST 比 GET 安全」——两者在网络上都是明文,HTTPS 才有加密;POST 只是不会留在浏览历史里。
- 「方法名能当权限用」——协议不管这个,必须在应用层校验。
自测三问(点开对答案)
1. 幂等的准确定义? —— 执行一次与执行多次,对资源状态的影响相同。不要求「无副作用」。 2. 为什么 PUT 幂等而 POST 不幂等? —— PUT 的语义是「把资源设为这个样子」,重复执行结果一样; POST 是「请处理」,每执行一次可能产生一个新结果。 3. HEAD 请求的响应有什么特别? —— 有首部和 Content-Length,但**没有正文**。按长度等待正文会一直卡住。方法列完了。下一节换个角度:这些方法为什么这么设计。
- ☐ (本节完,下一节 2.6 使用方法下达命令)