# 理解请求方法
30 秒速记
- 方法 = 客户端想对资源做的动作,
HTTP/1.1定义了8个:GET、HEAD、POST、PUT、DELETE、OPTIONS、TRACE、CONNECT,PATCH是后来RFC 5789补的 - 方法只是「意图声明」,服务器实际干什么由代码决定,
GET里删数据协议拦不住 - 安全 = 不改服务器状态:
GET、HEAD、OPTIONS、TRACE - 幂等 = 执行一次和十次结果一样:安全方法 +
PUT、DELETE;POST、PATCH都不保证 - 工程意义:浏览器、爬虫、预取、代理会默认安全方法可以随便发、幂等方法可以自动重试
请求方法就是告诉服务器「我想对这个资源做什么」,但它只是一个约定,服务器写成什么样就是什么样。 最常用的是 GET 取数据、POST 提交数据,PUT 整体替换、DELETE 删除,HEAD 只要头不要正文。真正值得讲的是两个属性:安全,就是不改服务器数据;幂等,就是重复执行结果一样。这不是学术概念,浏览器预加载、爬虫抓取会放心地发 GET,代理和客户端会自动重试幂等请求,所以你要是在 GET 里改库存,迟早被这些「放心的调用」搞出事故。
请求方法的两个属性可以用一张表记住:
| 方法 | 安全 | 幂等 | 常见用途 |
|---|---|---|---|
GET |
是 | 是 | 读取资源 |
HEAD |
是 | 是 | 只取头部,探测资源是否存在、多大、有没有更新 |
OPTIONS |
是 | 是 | 查询支持的方法,CORS 预检就用它 |
TRACE |
是 | 是 | 回显请求链路,线上一般禁用,防跨站追踪 |
PUT |
否 | 是 | 整体替换指定 URI 的资源 |
DELETE |
否 | 是 | 删除资源 |
POST |
否 | 否 | 提交数据、创建资源、各种不好归类的操作 |
PATCH |
否 | 否 | 局部修改 |
CONNECT |
否 | 否 | 通过代理建立隧道,HTTPS 走代理时用 |
「安全」指的是请求不应该改变服务器上的资源状态,记日志、计数这类附带效果不算。「幂等」指的是同一个请求发一次和发多次,服务器最终状态相同。
为什么前端要关心这个?看一段很常见的重试封装:
const IDEMPOTENT = new Set(['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE'])
async function request(url, options = {}, retries = 2) {
const method = (options.method || 'GET').toUpperCase()
try {
return await fetch(url, options)
} catch (err) {
// 只有网络层失败才会走到这里,4xx / 5xx 不会 reject
if (retries > 0 && IDEMPOTENT.has(method)) {
return request(url, options, retries - 1)
}
throw err // POST 失败直接抛,交给用户决定要不要再点一次
}
}
POST 失败时,请求可能根本没到服务器,也可能服务器已经处理完、只是响应在路上丢了,客户端分不清。盲目重试,下单就会变成下两单。要让 POST 也能安全重试,就由客户端生成一个唯一的 Idempotency-Key 放进请求头,服务端记录处理过的键,重复的键直接返回第一次的结果。
面试官追问
追问 1有个 GET /api/stock/reduce 接口在减库存,有什么问题?
GET 被默认为安全方法,浏览器预取、爬虫、CDN 回源、用户刷新都可能触发它,库存会被莫名其妙扣掉。改成 POST,或者按资源语义用 PATCH /api/stock/123。
追问 2PUT 和 POST 都能创建资源,区别在哪?
PUT /articles/42 是「把 42 号资源设成这样」,URI 由客户端定,执行多少次结果都一样,是幂等的;POST /articles 是「交给你处理」,服务器分配 id,执行两次就是两篇文章。所以网络超时后 PUT 可以放心重试,POST 不行。
追问 3重试组件要自动重放失败请求,哪些方法能放?
默认只放幂等的:GET、HEAD、OPTIONS、PUT、DELETE。POST、PATCH 要重试,必须让后端支持幂等键,比如请求头带 Idempotency-Key: 唯一ID,服务端看到重复的键直接返回上次结果。
追问 4DELETE 是幂等的,可第二次删同一个资源返回 404,这还算幂等吗?
算。幂等说的是服务器状态,不是响应内容:删一次和删十次,资源都是「不存在」,状态一致。返回 200 还是 404 只是告诉你这一次发生了什么。
追问 5监控每分钟探测一次文件是否更新,用 GET 还是 HEAD?
用 HEAD。它返回和 GET 一样的头部(Content-Length、Last-Modified、ETag),但不传正文,大文件能省下全部流量。前提是服务端正确实现了 HEAD,大部分框架会自动处理。
# 标准请求方法
30 秒速记
HTTP/1.1定义了 8 个:GET/HEAD/POST/PUT/DELETE/CONNECT/OPTIONS/TRACE,方法名区分大小写,标准写法全大写- 读:
GET拿资源,HEAD= 只要响应头的GET,不能带响应体 - 写:
POST把数据交给服务器处理(多是新建),PUT用请求体整体替换某个确定的URI,DELETE删 - 探测 / 特殊:
OPTIONS问能用哪些方法(CORS预检就是它),CONNECT让代理开隧道(走代理访问HTTPS),TRACE回显请求,线上基本都关掉 - 方法只是「意图」,删不删得掉、有没有权限,还是服务器说了算;
PATCH是后来单独补的,不在这 8 个里
HTTP/1.1 标准里有 8 个请求方法,日常真正天天用的是 GET、POST,接口规范一点会再加上 PUT、DELETE。 可以把方法理解成告诉服务器「我想干嘛」的动词:GET 读、HEAD 只看头不要内容、POST 提交、PUT 整体替换、DELETE 删除。剩下三个偏底层,OPTIONS 前端最常碰到,跨域预检发的就是它;CONNECT 是浏览器走代理访问 HTTPS 时让代理建隧道用的;TRACE 会把请求原样回显,有安全风险,网关一般直接禁掉。还有一点要说清,方法只表达意图,发了 DELETE 也可能因为没权限拿到 403。
目前
HTTP/1.1规定了八种方法,单词都必须是大写的形式
GET:获取资源,可以理解为读取或者下载数据;HEAD:获取资源的元信息;POST:向资源提交数据,相当于写入或上传数据;PUT:类似POST;DELETE:删除资源;CONNECT:建立特殊的连接隧道;OPTIONS:列出可对资源实行的方法;TRACE:追踪请求 - 响应的传输路径

原理拆解: 方法名是请求行的一部分,用来声明客户端的操作意图。方法区分大小写,标准方法通常使用大写。GET、HEAD 面向读取,其中 HEAD 的响应不得包含消息正文,但响应头应尽量与对应 GET 一致;POST 把数据交给目标资源处理,PUT 则倾向于用请求内容创建或替换指定 URI 的资源状态。DELETE 只要求服务器执行删除语义,不保证文件立即消失。OPTIONS 探测通信能力,TRACE 回显请求链路,CONNECT 建立到目标主机的隧道。
最小验证: 输入一条 OPTIONS 请求,验证服务器可通过 Allow 声明该资源支持的方法:
OPTIONS /articles/42 HTTP/1.1
Host: api.example.com
Origin: https://www.example.com
Connection: close
HTTP/1.1 204 No Content
Allow: GET, HEAD, PUT, DELETE, OPTIONS
Content-Length: 0
Connection: close
请求行中的 /articles/42 是探测目标,响应的 Allow 给出服务器愿意接受的方法;预期没有响应正文。若服务器未实现 OPTIONS,可能返回 405 Method Not Allowed 或 501 Not Implemented,不能据此推断协议中不存在该方法。
边界与排查: 方法语义不等于权限和执行结果:支持 DELETE 的路由仍可因鉴权失败返回 403,也可因资源不存在返回 404。HEAD 若错误返回正文,通常是框架路由或中间件实现不规范。代理常限制 TRACE,因为回显内容存在安全风险;CONNECT 也通常只对允许的目标开放。验证时应同时检查请求行、状态码、Allow 等响应头,以及网关是否在请求到达应用前拦截了方法。
面试官追问
追问 1HEAD /reports/42 返回了完整的报表正文,这算实现有问题吗?
算。HEAD 的约定就是响应头和 GET 一样、但不带响应体,常用来探文件大小、看 Last-Modified。多半是框架把 HEAD 直接路由到 GET 的处理函数,忘了丢掉 body,Express 这类框架会自动处理,手写路由的就容易漏。
追问 2前端想知道某个接口支不支持 DELETE,除了翻文档还能怎么问?
发一个 OPTIONS,看响应的 Allow 头,比如 Allow: GET, HEAD, PUT, DELETE
