4、HTTP请求方法详解:GET、POST、PUT、DELETE……

HTTP请求方法,说白了就是客户端告诉服务器“我想干什么”。一共定义了9种,但日常开发中常用的也就那么四五个。我刚开始做接口联调时,经常把POST和PUT搞混,直到有一次在生产环境上把数据重复插入了两遍……嗯,从那以后我对每个方法的语义都特别较真。

咱们一个一个来看,每种方法我都会结合抓包的实际场景讲。

4.1 GET方法——最常用的“查”

GET就是去服务器拿资源。浏览器输入网址、点击链接、加载图片,全是GET。它的特点是:幂等、安全、可缓存。

  • 幂等:你请求100次和请求1次,服务器上的资源状态不变。
  • 安全:不会修改服务器上的数据。
  • 可缓存:浏览器和代理服务器可以缓存GET响应。

抓包要点:GET请求没有请求体,参数全在URL的查询字符串里。你在Wireshark里看,一个GET包的结构就是:请求行 + 请求头 + 空行。干净利落。

GET /api/users?id=123&page=1 HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0
Accept: application/json

我曾经踩过的坑:URL长度限制。虽然HTTP协议本身没规定GET的URL长度,但浏览器和服务器都有隐含限制。IE限制2083字符,Nginx默认是8K。有一次我传了个Base64编码的大参数,结果被截断了,后端收到的是残缺数据。排查了半天才发现是URL超长。

4.2 POST方法——最常用的“增改”

POST用来提交数据给服务器,通常用于创建资源。它的核心特征是:非幂等、不安全、不可缓存(默认)。

你提交表单、上传文件、发JSON数据,基本都是POST。数据放在请求体里,Content-Type告诉服务器怎么解析。

POST /api/users HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 45

{"name":"张三","age":28,"email":"zhang@example.com"}
属性 GET POST
请求体 无 有
幂等性 是 否
安全性 是 否
可缓存 是 仅支持特定条件
URL参数 查询字符串 请求体
数据长度 有限制 理论上无限制

个人习惯:我写RESTful API时,创建资源用POST,更新用PUT,部分更新用PATCH。这样语义清晰,别人接手代码一看就懂。

4.3 PUT方法——全量替换

PUT是幂等的。你发一次和发十次,最终资源状态是一样的。它要求客户端提供完整的资源表示,服务器用这个表示替换已有的资源。

PUT /api/users/123 HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 60

{"id":123,"name":"李四","age":30,"email":"li@example.com"}

注意:如果资源不存在,有些实现会创建它(upsert),有些会返回404。我个人建议严格遵循语义——PUT只做替换,创建用POST。

4.4 DELETE方法——删除资源

DELETE也是幂等的。第一次删除返回200或204,第二次再删同一个资源,服务器应该返回404(资源已不存在),但资源状态没变——还是不存在。

DELETE /api/users/123 HTTP/1.1
Host: example.com

我曾经遇到的坑:DELETE请求的请求体。有些开发者习惯在DELETE里带请求体传参数,但很多代理服务器和网关会丢弃DELETE的请求体。我建议参数放URL路径或查询字符串里,别放body。

4.5 HEAD方法——只要响应头

HEAD和GET几乎一样,唯一的区别是服务器不返回响应体。用来检查资源是否存在、获取元数据(Content-Length、Content-Type、Last-Modified等)。

我常用HEAD做资源探测。比如下载大文件前,先发个HEAD看看文件大小,再决定要不要下载。

HEAD /bigfile.zip HTTP/1.1
Host: download.example.com

// 响应
HTTP/1.1 200 OK
Content-Length: 1048576000
Content-Type: application/zip
Last-Modified: Mon, 15 Jan 2024 10:30:00 GMT

4.6 OPTIONS方法——探路先锋

OPTIONS用来查询服务器支持哪些方法。响应头Allow字段会列出允许的方法列表。这在CORS(跨域)场景下特别常见——浏览器发预检请求时用的就是OPTIONS。

OPTIONS /api/users HTTP/1.1
Host: example.com
Origin: https://frontend.com
Access-Control-Request-Method: POST

// 响应
HTTP/1.1 204 No Content
Allow: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin: https://frontend.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS

避坑指南:OPTIONS请求不会携带认证信息(Cookie、Authorization头)。如果你的API需要鉴权,别在OPTIONS上做校验,否则预检请求会失败。

4.7 PATCH方法——局部更新

PATCH和PUT的区别:PUT是全量替换,PATCH是局部修改。你只传要改的字段,服务器只更新这些字段。

PATCH /api/users/123 HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 18

{"age": 31}

PATCH不是幂等的。比如你发“给age加1”,发两次结果不一样。这一点要特别注意。

4.8 TRACE方法——诊断回显

TRACE让服务器把收到的请求原样返回。用来诊断请求在传输过程中有没有被篡改(比如被代理服务器修改了头)。

不过说实话,生产环境基本不用。因为TRACE存在安全风险(跨站追踪攻击),大多数服务器默认关闭它。

TRACE / HTTP/1.1
Host: example.com
X-Forwarded-For: 192.168.1.1

// 响应
HTTP/1.1 200 OK
Content-Type: message/http

TRACE / HTTP/1.1
Host: example.com
X-Forwarded-For: 192.168.1.1

4.9 CONNECT方法——隧道代理

CONNECT用于建立隧道,最常见的就是HTTPS代理。客户端通过CONNECT告诉代理服务器“我要连接到目标服务器的443端口”,代理建立TCP隧道后,客户端和服务器直接进行TLS握手。

CONNECT example.com:443 HTTP/1.1
Host: example.com:443

// 响应
HTTP/1.1 200 Connection Established

之后所有数据都在隧道里加密传输,代理只负责转发,看不到内容。

HTTP 请求方法知识体系 HTTP 请求方法 安全 & 幂等 非安全 & 非幂等 特殊用途 GET HEAD OPTIONS DELETE POST PATCH PUT TRACE CONNECT 核心原则 安全方法不修改资源 · 幂等方法多次调用结果一致 · 语义化使用让接口更清晰

4.10 抓包实战建议

最后分享几个抓包时的实用技巧:

  1. 过滤方法:在Wireshark里用 http.request.method == POST 快速定位特定方法的请求。
  2. 关注响应码:GET成功返回200,POST创建成功返回201,DELETE成功返回204,PUT成功返回200或204。
  3. 注意缓存:GET请求会被浏览器缓存,调试时记得勾选“Disable cache”。
  4. OPTIONS预检:看到非简单请求(比如带自定义头、Content-Type为application/json)先发OPTIONS,这是CORS机制,别慌。

我个人习惯:每次接手新项目,第一件事就是抓包看接口用了哪些方法。如果全是POST,那这个项目的RESTful风格基本没落地。如果GET、POST、PUT、DELETE分得很清楚,说明团队有规范,代码质量通常不会太差。