在 Web 开发与日常面试中,HTTP 协议是绕不开的高频考区。很多人能说出 GET 和 POST 的基础区别,但被问到"PUT 和 POST 的本质区别"、"DELETE 到底是不是幂等的"、"跨域时的 OPTIONS 请求是怎么回事"时,往往会语塞。
本文将从底层逻辑到应用场景,详细梳理 HTTP 最常用的 5 种请求方法。
第一部分:前置核心概念
在具体分析请求方法之前,需要先理清两个维度的基本认知:数据搭载的位置,以及安全性和幂等性的定义。
1. 数据可以搭载在哪里?
一个完整的 HTTP 请求由请求行(包含 URL)、请求头(Headers)、请求体(Body)组成。客户端给服务端传数据,主要有以下三个位置:
- URL 路径与查询字符串(Path & Query)
直接暴露在网址中(如 /users/123?name=tom)。特点是直观、可被浏览器缓存。但受限于浏览器和服务器对 URL 长度的限制,且数据明文暴露在浏览器历史记录和服务器日志中,安全性极低。
Path(路径参数)
位置:URL 的主体部分,位于域名之后,问号(?)之前。
结构:由斜杠(/)分隔。
示例:https://api.example.com/users/1024/orders/5
含义:其中的 1024 和 5 就是路径参数,分别代表用户 ID 和订单 ID。
Query(查询字符串)
位置:URL 的末尾,以问号(?)开头。
结构:以键值对(key=value)形式出现,多个参数用 & 连接。
示例:https://api.example.com/users?role=admin\&sort=asc
含义:其中的 role=admin 和 sort=asc 是查询参数,用于过滤或排序。 - 请求头(Headers)
存在于 HTTP 报文的头部。通常用于传递元数据,比如认证 Token、客户端信息、内容类型等,一般不用于承载核心业务数据。 - 请求体(Body)
位于 HTTP 报文的内部。用于传输大量数据或复杂数据结构(如 JSON、文件、表单)。大小基本无限制,且不会保存在浏览器的历史记录中。
2. 标准语义:安全性与幂等性
面试官评判你是否真正理解 RESTful 规范,通常会考察这两个概念:
- 安全性(Safe)
如果一个请求方法仅仅是获取资源,而不会改变服务器的状态(即只读操作),那么它就是安全的。 - 幂等性(Idempotent)
一个操作执行一次和执行成百上千次,对服务器状态产生的影响是完全相同的。通俗来说,无论重复操作多少次,结果都和操作一次一样。
第二部分:5 种核心请求方法解析
基于前置概念,我们逐一分析这 5 种常用请求。
1. GET
- 核心语义:请求获取指定资源。
- 数据搭载位置:URL(路径或查询参数)。HTTP 规范并未严令禁止 GET 携带请求体,但在实际应用中,浏览器和代理服务器通常会忽略 GET 的 Body。因此,标准规范下 GET 传参依赖 URL。
- 安全性:安全。只是读取数据,不修改服务器数据。
- 幂等性:幂等。读一次和读一万次,服务器里的数据状态不会改变。
- 缓存特性:通常会被浏览器主动缓存。
2. POST
- 核心语义:向指定资源提交数据,通常用于创建新资源或执行复杂的、非标准化的操作。
- 数据搭载位置:请求体(Body)。数据格式由请求头中的 Content-Type 决定。
- 安全性:不安全。会在服务器创建数据或触发业务逻辑,改变了服务器状态。
- 幂等性:非幂等。例如用 POST 提交一次订单,生成一个订单号;重复提交则会生成多个不同的订单,服务器状态发生了多次改变。
- 缓存特性:默认不会被缓存。
3. PUT
- 核心语义:向指定位置上传最新内容,整体替换目标资源。如果资源不存在,则创建它。
- 数据搭载位置:请求体(Body)。URL 必须精确指向要更新的资源(如 /users/123)。
- 安全性:不安全。修改了服务器数据。
- 幂等性:幂等。这是 PUT 和 POST 的最核心区别。例如把 ID 为 123 的用户年龄修改为 20 岁,这个请求发送一次和发送一万次,该用户的年龄最终都是 20 岁,服务器的最终状态是一致的。
4. DELETE
- 核心语义:请求服务器删除指定的资源。
- 数据搭载位置:URL 路径(如 /users/123)。和 GET 类似,标准不建议 DELETE 携带 Body。
- 安全性:不安全。删除了数据,改变了服务器状态。
- 幂等性 :幂等。
- 面试常考点:第一次删除返回 200,第二次删除返回 404,响应结果变了,这还叫幂等吗?
- 答案是肯定的。幂等性关注的是"服务器的状态",而不是"响应的状态码"。资源被删除后,无论再发多少次 DELETE 请求,该资源在服务器上"不存在"的状态是没有改变的。
5. OPTIONS
- 核心语义:获取服务器支持的 HTTP 请求方法(通信选项),或者在跨域时进行预检(Preflight)。
- 数据搭载位置:无需携带业务数据,仅依赖 URL 和请求头。
- 安全性:安全。只询问,不操作。
- 幂等性:幂等。
- 核心应用场景(跨域预检):当浏览器发起一个跨域的复杂请求(如使用 PUT 方法,或带有自定义 Header 的 POST 请求)时,浏览器会先自动发送一个 OPTIONS 请求到服务器。这个请求用于询问服务器是否允许该跨域操作。如果服务器回复允许,浏览器才会发送真正的业务请求。这就是 CORS(跨源资源共享)的预检机制。
第三部分:总结与面试进阶
为了方便记忆,将上述核心点总结如下:
| HTTP 方法 | 核心动作 | 数据主要位置 | 安全性 | 幂等性 | 是否可缓存 |
|---|---|---|---|---|---|
| GET | 获取资源 | URL | 安全 | 幂等 | 是 |
| POST | 创建/处理数据 | 请求体 | 不安全 | 非幂等 | 否 |
| PUT | 替换/更新资源 | 请求体 | 不安全 | 幂等 | 否 |
| DELETE | 删除资源 | URL | 不安全 | 幂等 | 否 |
| OPTIONS | 跨域预检/嗅探 | 请求头 | 安全 | 幂等 | 否 |
面试进阶问题
问:既然从 TCP 层面看,GET 和 POST 底层都是 TCP 连接,它们真的有本质区别吗?
答:如果抛开 HTTP 规范,只谈底层 TCP,它们确实没有本质区别,都是发送和接收字节流。你甚至可以在 GET 请求中强行塞入 Body,或者在 POST 请求中把参数全写在 URL 上。
但是,这种做法在实际工程中是不可取的。RESTful API 及 HTTP 请求方法的意义在于语义化与契约精神。浏览器、代理服务器(如 Nginx)、CDN 都是基于 HTTP 标准语义来工作的。如果违反规范(例如用 GET 做删除操作),一旦搜索引擎的爬虫或者浏览器的预加载机制触发了你的 GET 接口,可能会导致严重的数据安全问题。因此,遵从标准语义,是前后端以及基础架构之间能够稳定协作的基础。