HTTP 中 GET 和 POST 的区别是什么:从语义到安全、从参数到缓存

张开发
2026/4/19 1:06:49 15 分钟阅读

分享文章

HTTP 中 GET 和 POST 的区别是什么:从语义到安全、从参数到缓存
HTTP 中 GET 和 POST 的区别是什么从语义到安全、从参数到缓存01. 前言最经典也最容易被误解的面试题02. 一句话核心区别03. GET 方法详解3.1 语义获取资源3.2 GET 请求示例3.3 GET 的特点3.4 GET 的缓存流程图04. POST 方法详解4.1 语义提交数据4.2 POST 请求示例4.3 POST 的特点4.4 POST 刷新/后退时的行为流程图05. 核心区别深入分析5.1 幂等性Idempotent5.2 安全性SecurityHTTP 规范层面的“安全”5.3 参数长度限制的真相5.4 数据类型的支持06. 对比总表07. 使用场景指南何时使用 GET何时使用 POST反例警示08. 常见误区澄清09. 完整决策流程图10. 总结The Begin点点关注收藏不迷路01. 前言最经典也最容易被误解的面试题在 HTTP 方法家族中GET和POST是最常用、也最容易混淆的一对。很多初学者认为“GET 把参数放在 URL 里POST 把参数放在 body 里”——这虽然没错但只是冰山一角。真正的区别远不止参数位置幂等性、缓存策略、安全性语义、数据长度限制、历史记录行为……本文从 HTTP 规范到实际浏览器行为全面拆解 GET 与 POST 的核心差异。02. 一句话核心区别维度GETPOST语义获取资源不应改变服务器状态提交数据通常会改变服务器状态参数位置URL 查询字符串?keyvalue请求体Request Body幂等性是多次请求结果相同否多次请求可能创建多个资源缓存可缓存默认不可缓存除非特殊配置安全性参数暴露在 URL历史记录、服务器日志参数在 body 中相对隐蔽但非加密长度限制受 URL 长度限制约 2KB~8KB视浏览器理论上无限制受服务器配置限制书签/保存可以保存为书签不可以浏览器后退无影响可正常重放会弹窗警告“是否重新提交表单”03. GET 方法详解3.1 语义获取资源GET 方法的语义是请求服务器返回某个资源且不应该产生副作用——即不会修改服务器上的数据不增、不改、不删。3.2 GET 请求示例GET /api/users?page2size10name张三 HTTP/1.1 Host: example.com User-Agent: Mozilla/5.0 Accept: application/json参数全部附加在 URL 的?之后键值对用连接。3.3 GET 的特点特点说明参数在 URL可见、可分享、可收藏长度有限浏览器限制 URL 长度IE ~2KBChrome ~8KB理论 2048 字符常见只接受 ASCII 字符中文/特殊字符需 URL 编码如%E5%BC%A0会被浏览器缓存相同 URL 再次请求可能直接从缓存读取保存在历史记录完整 URL含参数会被保存敏感信息泄露风险服务器日志可见Web 服务器默认记录完整 URL参数会被记录3.4 GET 的缓存流程图客户端发起 GET 请求 │ ▼ 检查浏览器缓存 │ ├── 命中缓存且未过期 ──→ 直接使用缓存不发请求 │ └── 未命中或已过期 │ ▼ 发送 GET 请求到服务器 │ ▼ 服务器返回响应 缓存头Cache-Control, Expires │ ▼ 存入缓存返回给客户端04. POST 方法详解4.1 语义提交数据POST 方法的语义是向服务器提交数据通常会产生状态变化——创建新资源、更新数据、触发某个动作。4.2 POST 请求示例POST /api/users HTTP/1.1 Host: example.com Content-Type: application/json Content-Length: 56 { name: 张三, age: 25 }参数放在请求体中格式由Content-Type决定。4.3 POST 的特点特点说明参数在 bodyURL 中不暴露参数相对隐蔽长度无理论限制受服务器配置限制如 Nginxclient_max_body_size默认 1MB支持任意字符/二进制可传输文件、JSON、XML、纯文本等各种格式不会被缓存默认除非显式配置Cache-Control不保存在历史记录历史记录只显示 URL不显示 body服务器日志不记录 body默认只记录 URLbody 需额外配置才能记录后退/刷新会弹窗浏览器会提示“是否重新提交表单”防止重复提交4.4 POST 刷新/后退时的行为流程图用户提交 POST 表单 │ ▼ 服务器处理并返回响应页面 │ ▼ 用户点击“后退”按钮 │ ▼ 浏览器检测到上次请求是 POST │ ▼ ┌─────────────────────────────────┐ │ 弹窗警告 │ │ “是否重新提交表单” │ │ [确认] [取消] │ └─────────────────────────────────┘ │ ├── 确认 → 重新发送 POST 请求可能导致重复提交 │ └── 取消 → 停留在当前页面05. 核心区别深入分析5.1 幂等性Idempotent方法幂等性说明GET✅ 是请求一次与请求 N 次服务器状态相同资源内容不变POST❌ 否请求一次创建 1 条订单请求两次创建 2 条订单状态会改变幂等性示例 GET /user/123 → 第 1 次返回用户信息第 2 次返回相同信息不变 POST /order → 第 1 次创建订单 #1001第 2 次创建订单 #1002不同幂等性是 GET 可以被安全重试网络超时自动重试的基础。5.2 安全性SecurityHTTP 规范层面的“安全”HTTP 规范中“安全方法”指不会改变服务器状态的方法。GET安全方法只读POST不安全方法会改变状态⚠️ 注意这里的“安全”不是指加密HTTPS 才是加密。GET 的明文参数仍可被窃听。5.3 参数长度限制的真相很多人说“GET 有长度限制POST 无限制”——这个说法不完全准确HTTP 规范本身没有对 GET 的 URL 长度做限制实际限制来源浏览器IE ~2083 字符Chrome ~8182 字符Web 服务器Nginxlarge_client_header_buffersApacheLimitRequestLine中间代理/CDN浏览器/服务器URL 长度上限约IE 112048 字符Chrome8182 字符Firefox65536 字符Safari80000 字符Nginx默认8KBPOST 的 body 长度理论上无限制实际受服务器配置限制Nginxclient_max_body_size默认 1MB可调至 GB 级5.4 数据类型的支持数据类型GETPOSTASCII 文本英文/数字✅ 支持✅ 支持中文/Unicode✅ 需 URL 编码✅ 支持UTF-8二进制/文件❌ 不支持✅ 支持multipartJSON/XML 结构化数据❌ 不推荐URL 过长✅ 支持06. 对比总表对比维度GETPOST浏览器后退/刷新无影响弹窗警告“是否重新提交”书签可保存为书签不可保存缓存默认可缓存默认不缓存编码类型application/x-www-form-urlencodedmultipart/form-data或application/json等多种历史记录完整 URL含参数被保存仅 URL 保存不保存 body限制URL 长度限制请求体大小限制服务器配置安全性隐私参数暴露在 URL地址栏、日志、Referer参数在 body 中相对隐蔽数据包一个 TCP 包头部数据两个 TCP 包先发头后发 body** 部分浏览器/服务器实现中POST 可能分两次发送Expect: 100-continue 场景。07. 使用场景指南何时使用 GET搜索/查询/search?qkeyword获取资源列表/api/users?page1查看详情/product/123任何只读、不改变服务器状态的操作何时使用 POST创建新资源注册用户、发布文章、创建订单登录/提交表单文件上传触发某个动作发送邮件、执行脚本传输大量数据或复杂结构JSON/XML反例警示❌ 错误用 GET 删除用户 GET /api/user/delete?id123 → 爬虫/预加载可能误删数据 ✅ 正确用 DELETE 或 POST DELETE /api/user/123 或 POST /api/user/deletebody: { id: 123 }08. 常见误区澄清误区真相“POST 比 GET 更安全”只表示参数不在 URL 暴露但明文传输时两者都不安全。加密需用 HTTPS。“GET 只能传文本POST 能传文件”正确因为 GET 参数在 URLURL 不支持二进制。“POST 没有长度限制”实际上受服务器配置限制只是比 GET 的 URL 限制宽松得多。“浏览器对 GET 和 POST 一样处理”不同GET 可缓存、可收藏、后退无弹窗POST 则相反。“所有表单都应该用 POST”搜索框等只读操作应使用 GET便于分享和收藏。09. 完整决策流程图是否需要改变服务器状态 │ ├── 否只读─────────────────────────────────┐ │ │ └── 是写入/修改/删除 │ │ │ ▼ ▼ 使用 POST 是否需要分享/收藏 或 PUT/DELETE │ │ ├── 是 ──→ 使用 GET │ │ ▼ └── 否 考虑是否幂等 │ │ ▼ ├── 是如 PUT────────────→ 可使用 GET 或 PUT │ └── 否如 POST、PATCH 附加考虑因素 - 数据量大小大 → POST - 是否含文件是 → POSTmultipart - 参数敏感性高 → POST配合 HTTPS - 需要缓存是 → GET10. 总结┌─────────────────────────────────────────────────────────────┐ │ GET vs POST 核心口诀 │ ├─────────────────────────────────────────────────────────────┤ │ GET 查数据参数跟着 URL 走 │ │ POST 改数据参数放 body 里头 │ │ GET 可缓存、可收藏、后退不用愁 │ │ POST 不缓存、不收藏、后退问是否 │ │ 敏感数据用 POST 也不够必须配上 HTTPS 才安全 │ └─────────────────────────────────────────────────────────────┘最终建议严格遵循 HTTP 语义GET 只读POST 写入不要用 GET 传递密码、token 等敏感信息即使有 HTTPSURL 也会留在浏览器历史、服务器日志需要缓存和分享的查询接口坚决用 GET文件上传、大数据、敏感表单用 POST HTTPSThe End点点关注收藏不迷路

更多文章