HTTP 请求
快速阅读
| 方法 | 安全 | 幂等 | 用途 |
|---|---|---|---|
GET |
是 | 是 | 获取资源 |
HEAD |
是 | 是 | 获取元信息 |
POST |
否 | 否 | 提交数据 |
PUT |
否 | 是 | 全量替换资源 |
PATCH |
否 | 否 | 局部更新资源 |
DELETE |
否 | 是 | 删除目标资源 |
OPTIONS |
是 | 是 | CORS 预检 |
TRACE |
是 | 是 | 调试诊断 |
CONNECT |
否 | 否 | HTTPS 代理 |
GET
用途
GET 是 HTTP 协议中最常用的方法,作用是 从服务器获取资源,规范语义上属于 只读操作,不能修改服务器的数据。
GET 的使用场景有:
- 获取静态资源:HTML 页面、CSS、JS、图片、视频、音频等,可被浏览器 / CDN 缓存,提升访问速度;
例如:GET /index.html HTTP/1.1 - 查询接口,读取业务数据:列表查询、详情查询、搜索功能等;
例如:GET /api/article?id=1024 HTTP/1.1 - 页面跳转和分享链接:
GET的查询参数可以完整保留在 URL 中,可用于链接跳转。
例如:https://example.com/share?invite=9sK7g2pR5xQ8zD2
特点
通过查询字符串传递参数
GET 不使用请求体,而是通过查询字符串传递参数,这些字符串会出现在浏览器历史记录和书签等场景,不适合携带敏感信息(密码、Token 等)。
URL 中 ? 后面是查询参数部分,多个参数用 & 分隔,中文和特殊符号需要进行 URL 编码:
A-Z a-z 0-9 - _ . ~属于 未保留字符,不需要编码;: / ? # [ ] @ ! $ & ' ( ) * + , ; =属于 保留字符,不会自动编码;- 其他所有字符(中文、空格、控制字符等),属于 非法字符,都需要编码。
在浏览器地址栏填入 URL 会自动编码,例如填入 https://example.com/api?note=项目&说明=版本1.0,地址栏页面上依旧显示为中文,但实际的请求已经编码过。
URL 解析器对输入的 URL 进行 整体编码 时,只会编码 非法字符,不会编码 保留字符,如果保留字符刚好属于 内容部分,会导致服务端解析错误。
通过 fetch 等方法发送请求,URL 会自动编码:
1 | const note = "项目&模块A"; |
URL 会自动进行整体编码,但是 URL 解析器无法识别在整个字符串中 & 是作为内容还是分隔符,实际上它属于合法的保留字符不会被编码,会导致服务端解析错误。
最标准的写法是使用 URL + URLSearchParams:
1 | const url = new URL("https://example.com/api"); |
url.searchParams.set 会覆盖同名 key;url.searchParams.append 不会覆盖而是追加一条,很多后端框架会把 多值参数 整合为一个数组。
手动构造原始 HTTP 报文时不会自动编码:
1 | GET /api?content=项目&模块A |
服务器会识别为两个参数:content='项目',模块A=''。
如果发送到服务端的 URL 中包含非法字符,例如空格:
1 | GET /search?q=hello world HTTP/1.1 |
服务器会解析为 方法: GET; 请求目标: /search?q=hello; HTTP 版本: world,返回 400 Bad Request,请求格式错误。
如果 URL 包含中文字符,服务器不做严格校验时会按原始字节解析,可能出现乱码;其他非法字符严格服务器会返回 400 Bad Request,宽松服务器会按字面解析,但可能出现安全漏洞(CRLF 注入 等)。
安全与幂等
GET 规范语义上是 安全方法,不改变服务器状态。浏览器、爬虫等可以自动发起 GET 请求,不会破坏服务器数据。
安全方法强调 不修改数据、无副作用,是否可以自动触发。
GET 规范语义上也是 幂等方法,多次执行效果相同。网络出错时,客户端可以自动重试 GET 请求。
幂等方法强调 重复执行,结果不变,是否可以自动重试。
缓存特性
GET 是 默认可缓存 的方法,允许浏览器、CDN、代理服务器存储该请求的响应,后续相同请求直接复用缓存,不用再次请求源服务器。
GET、HEAD 默认可缓存;POST 通常不可缓存,但在特定条件下可缓存;其他方法都不可缓存。POST 语义是 提交数据,通常有副作用,缓存一般只用于 GET 和 HEAD 方法。
示例
1 | GET /index.html |
响应
1 | 200 OK |
HEAD
用途
HEAD 用于 获取资源的元信息,但不获取资源本身,可以节省流量和时间。HEAD 方法和 GET 几乎完全相同,区别仅在于服务器只返回响应头,不返回响应体。
HEAD 的使用场景有:
- 检查资源是否存在和有效,只看状态码,不下载正文;
- 获取资源元信息,通过响应头识别资源类型、大小和修改时间;
- 预检重定向,检查 URL 是否需要跳转,客户端可以据此更新链接;
- 预检范围下载,下载大文件前,先发送
HEAD请求检查是否支持断点续传。
特点
无请求体
HEAD 方法通常无请求体,参数放在 URL 查询字符串中,与 GET 相同。
无响应体
规范上服务器对 GET 和 HEAD 的处理逻辑是相同的,唯一差别是服务器对 HEAD 只返回响应头,不返回响应体。
安全与幂等
HEAD 是 安全 方法,不修改服务器状态;HEAD 也是 幂等 方法,多次执行效果相同。
缓存特性
HEAD 响应 默认可缓存,但缓存的是头部信息,没有正文。
示例
1 | HEAD /file.zip |
响应
1 | 200 OK |
POST
用途
POST 用于 向服务器提交数据,可能会改变服务器的状态。与 GET 的 只读 形成对比,它是 Web 应用中最常用的 写操作。
POST 的使用场景有:
- 提交表单数据:HTML 表单默认用
POST方法提交,数据在请求体中,不暴露在 URL; - 上传文件:通过网页表单上传文件,标准做法是
POST+multipart/form-data; - 创建新资源:在服务端新增一条记录,例如发表一篇文章、新建用户账号、创建订单等;
- 提交复杂数据给接口:前端把结构化、多层嵌套的数据放在
POST请求体中,以JSON格式发送到后端接口。
特点
可携带大量数据
POST 请求的数据放在请求体中,不暴露在 URL,因此它 不可书签、不可分享、不被历史记录。请求体长度受服务器配置限制,但不受 URL 长度限制,可以携带大量数据。
浏览器的历史记录保存的主要是 用户主动发起的、可导航的 请求,本质是 可重新访问的 URL,并不是完整的 HTTP 报文,符合条件的一般都是 GET 方法。
安全与幂等
POST 不是安全方法,可能会修改服务器的状态;POST 也不是幂等方法,多次执行,效果可能不同。
POST 不必然改变服务器状态,它只是语义上 不保证安全,即客户端、代理、缓存不能假设 POST 是安全的,具体是否修改数据,由服务器实现决定,服务器完全可以用 POST 做只读操作。
爬虫通常不会主动发起 POST 请求,避免触发副作用。
缓存特性
POST 响应 默认不缓存,除非显式设置缓存头。
当查询参数巨大,无法放到 GET 的 URL 中(有长度限制),只能放在 POST 的请求体中,并且相同参数的查询结果固定不变时才会考虑使用 POST 缓存。服务端可以在响应中显式添加 Cache-Control 等缓存头,命中缓存需要 URL 与请求体都完全一致。
浏览器、CDN、代理服务器都支持 GET 缓存,命中条件只匹配 URL;而 POST 缓存 兼容性差,且要求 URL 和请求体都完全一致时才能命中缓存。
示例
1 | POST /api/comment |
响应
1 | 201 Created |
PUT
用途
PUT 用于 替换目标资源,必须上传 完整的资源数据,覆盖服务端该位置已存在的内容,若资源不存在,则创建。
PUT 用于整体更新资源,而非部分更新,请求体必须包含资源的完整表示,否则未提供的字段会丢失。
PUT 的使用场景有:
- 对象存储上传文件:指定路径上传文件,通过
PUT全量更新已有资源; - 静态站点部署:部署工具通常使用
PUT上传静态文件; - 覆盖配置文件:通过
PUT多次提交同一配置,结果相同; - 幂等状态设置:通过
PUT设置固定状态而非增量操作,网络中断后可安全重试。
特点
请求体是完整表示
PUT 的请求体必须包含资源的完整表示,不能是部分字段。
客户端指定 URI
PUT 方法需要客户端明确指定资源位置,而 POST 通常由服务器决定新资源的 URI。
URI(统一资源标识符)用来唯一标识一个资源,例如:urn:isbn:9780123456789;URL(统一资源定位符)用来定位一个资源,它是 URI 的子集,必须包含 访问地址,例如:https://opensrv.cloud/。
安全和幂等
PUT 不是安全方法,会修改服务器的状态;PUT 是幂等方法,网络中断后可安全重试,这是 PUT 与 POST 的核心区别。
缓存特性
PUT 响应 默认不缓存,缓存是为查询获取资源而设计的,PUT 语义是修改资源,实际几乎不会用到缓存。
示例
1 | PUT /my-bucket/images/pic.png |
响应
1 | 200 OK |
PATCH
用途
PATCH 用于对资源进行 部分修改,只发送需要修改的部分,而不是整个资源。
PATCH 的使用场景有:
- 局部更新资源:通过
PATCH方法修改对象的少数字段,只传需要变更的字段即可,传输体积更小; - 结构化补丁:
JSON Patch是一种用 JSON 文档描述修改操作的格式,是PATCH请求最常用的格式之一。
特点
部分修改
PATCH 的核心语义是 对目标资源应用部分修改,与 PUT 不同,PATCH 不会丢失未提供的字段。
通过指令修改
PATCH 的请求体是描述如何修改的指令,格式不唯一,由 Content-Type 约定,例如 application/json-patch+json 或 application/merge-patch+json。
安全与幂等
PATCH 会修改服务器的状态,不是安全方法;PATCH 可以通过 JSON Patch 的 add 操作向数组末尾追加元素,它也不是幂等方法。
缓存特性
PATCH 响应 默认不缓存。
示例
1 | PATCH /resources/10 |
原始资源
1 | { |
响应
1 | 204 No Content |
修改后的资源
1 | { |
DELETE
用途
DELETE 用于 删除目标资源,操作对象是整个资源,不是资源里的某个字段。
DELETE 的使用场景有:
- 删除指定资源,例如
DELETE /resources/10; - 删除用户账号,例如
DELETE /users/alice; - 删除文章、评论,例如
DELETE /articles/01/comments/201; - 取消订单、订阅,例如
DELETE /orders/6001。
特点
无请求体
DELETE 通常不携带请求体。
URI 指向具体资源
DELETE 的 URI 应该指向具体资源,而不是集合。
安全与幂等
DELETE 会修改服务器的状态,不是安全方法;但它是幂等方法,资源已被删除时返回 404。
缓存特性
DELETE 响应 默认不缓存。
示例
1 | DELETE /api/orders/1001 |
响应
1 | 204 No Content |
OPTIONS
用途
OPTIONS 用于 查询目标资源支持哪些 HTTP 方法,它是查询服务器能力的请求,不修改资源、不读写业务数据。
OPTIONS 的使用场景有:
- 查询某个端点支持的 HTTP 方法,服务器会返回
Allow响应头;
例如Allow: GET, POST, PUT, DELETE, OPTIONS - 查询服务器整体能力,但不代表每一个接口都支持全部方法;
例如OPTIONS * HTTP/1.1 - CORS 预检,浏览器在发送跨域复杂请求前,会先发一个
OPTIONS预检。
浏览器的跨域限制和 CORS 预检的目的都是为了 保护用户,而非保护服务器。
特点
无请求体
OPTIONS 通常不携带请求体。
无响应体
OPTIONS 响应通常无正文,信息都在头部字段。
安全与幂等
OPTIONS 是安全且幂等的方法,属于 只读请求。
缓存特性
OPTIONS 响应 默认不缓存,但 CORS 预检的结果可以被缓存,通过 Access-Control-Max-Age 控制。
示例
1 | OPTIONS /api/comments |
响应
1 | 204 No Content |
TRACE
用途
TRACE 用于 调试诊断,服务器会把收到的请求原样回显给客户端,让客户端能看到请求在传输过程中是否被修改。
TRACE 通常用来检查中间代理是否修改了请求。
特点
无请求体
TRACE 通常不携带请求体,响应体是收到的原始请求报文。
现代浏览器禁用
为了防止 XST 漏洞,大多数生产服务器禁用 TRACE 方法,浏览器也会阻止 JS 发送 TRACE 请求。
安全与幂等
TRACE 是安全且幂等的方法,无副作用。
缓存特性
TRACE 响应 默认不缓存,TRACE 用于诊断,响应是动态回显,缓存无意义。
示例
1 | TRACE /api/users |
响应
1 | 200 OK |
CONNECT
用途
CONNECT 用于 建立 TCP 隧道,客户端通过 HTTP 代理与目标服务器建立一条 TCP 连接,之后的数据不再走 HTTP 协议:客户端 ──CONNECT──► 代理服务器 ──TCP 连接──► 目标服务器。
CONNECT 通常用于 HTTPS 代理,当用户访问 HTTP 网站时,代理服务器会直接转发 HTTP 报文;而 HTTPS 是端到端加密的,访问 HTTPS 网站时,必须通过 CONNECT 方法请求代理服务器和目标服务器建立 TCP 连接,代理只会转发加密字节,不解析 HTTPS 报文内容。
HTTP 代理工作在 应用层,客户端会把完整的 HTTP 请求发给代理,代理必须 解析这个请求,并根据解析结果重新构造请求发给目标服务器;而 HTTPS 的 HTTP 报文被 TLS 加密了,目标地址也在加密内容中,只有目标服务器能够解析,所以不能用应用层代理的方式转发,必须用 CONNECT 方法建立 TCP 隧道,直接转发 HTTPS 的加密字节(CONNECT 一般是明文的 HTTP 请求,不是 HTTPS,它 必须能被代理服务器解析)。
CONNECT 是发送给代理服务器的请求,但 请求行写的是目标服务器的地址,客户端通过 TCP 协议与代理服务器建立连接,会主动把配置了代理的流量发送给代理服务器。
Clash Verge 等应用本质上属于代理客户端,核心功能是把流量转发给配置的代理服务器(机场节点),由代理服务器代为访问目标,并不属于 VPN。
特点
无请求体
CONNECT 通常不携带请求体。
请求目标是 host:port
CONNECT 的请求目标是 host:port 格式,不是路径。
安全与幂等
CONNECT 会产生连接状态,不是安全方法;CONNECT 也不是幂等方法,多次执行会带来不同的连接状态。
缓存特性
CONNECT 响应 默认不缓存,它建立的是有状态的连接,无法缓存。
示例
1 | CONNECT www.example.com:443 |
响应
1 | 200 Connection Established |





