GET 是什么
GET 是最基础的 HTTP 请求方法:向服务器索取目标资源的表示,不应产生任何副作用。RFC 9110 §9.3.1 定义它同时具备三个属性——安全(不改变服务端资源状态)、幂等(多次执行效果与一次相同)、可缓存(响应可被浏览器、CDN 与代理复用)。它是整个 Web 读取语义的基石:地址栏回车、页面超链接、图片与脚本加载,发的都是 GET。因为参数全在 URL 里,它天然会进入访问日志、浏览器历史、书签与爬虫抓取范围。
基本信息
| 名称 | GET |
|---|---|
| 作用 | 读取目标资源的表示,不应改变服务端状态 |
| 规范 | RFC 9110 §9.3.1;幂等性见 §9.2.2 |
| 特性 | 安全 + 幂等 + 可缓存 |
| 请求体 | 规范未赋予语义,实践中不应携带 |
典型使用场景
- 读取接口数据:列表、详情、搜索等只读查询
- 页面与静态资源加载:HTML、图片、样式表与脚本都由 GET 拉取
- 预取与抓取:搜索引擎收录、社交卡片预览都基于 GET
- 条件请求:配合校验头做协商缓存,命中则省下响应体
- 幂等重试:网络超时后可直接重发,不必担心重复写入
请求与响应报文
请求与响应报文
GET /api/users?id=42 HTTP/1.1
Host: api.example.com
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: max-age=60curl 常用写法
curl 常用写法
curl -s https://api.example.com/users?id=42 | jq . # 读取并格式化 JSON
curl -sI https://www.example.com/ # 只取响应头,不下载内容
curl -si -H 'If-None-Match: v17' https://static.example.com/app.js # 带校验值做条件请求,命中返回 304
curl -s -o /dev/null -w '%{http_code} %{time_total}\n' https://api.example.com/health # 只关心状态码与耗时响应头速读
| 头部 | 含义 | 正常与异常 |
|---|---|---|
| Content-Type | 响应体的媒体类型 | 缺失或类型不符会让客户端解析失败 |
| Cache-Control | 新鲜度与可缓存策略 | 带 no-store 时任何缓存都不得存储 |
| ETag 与 Last-Modified | 表示版本校验值 | 值变化说明资源已更新 |
| Content-Length | 报文长度 | 与 Transfer-Encoding 同时出现属异常 |
URL 长度没有统一的硬上限:过长的 URL 可能被网关、代理或 CDN 截断,各家阈值不同,因此不要依赖某个固定数字。查询条件特别多时,宁可改用请求体传参或精简字段。
把口令、令牌、身份证号之类的敏感信息放进 GET 查询串,会随 URL 流入浏览器历史、访问日志、来源头与 CDN 缓存,是典型的凭证泄漏路径。
缓存命中怎么观察
- 浏览器开发者工具的尺寸列显示来自磁盘缓存或内存缓存,说明强缓存命中,完全没有发出网络请求
- 协商缓存命中时状态码是 304,尺寸列只有很小一行,表示双方只交换了头部
- 命中失败会回到 200 并带回完整响应体,说明重新下载了全量内容
- 用命令行比对总耗时:强缓存命中几乎不耗时,协商缓存要多一个来回
- 改了内容却仍拿到旧版本,先查缓存指令与校验值,再查 CDN 是否另有一层缓存
URL 设计对缓存的影响
| 做法 | 影响 |
|---|---|
| 查询条件放在 URL 中 | 响应可被缓存与收藏,代价是参数会写进访问日志 |
| 同一内容用多组等价参数 | 参数顺序不同会被视为不同资源,缓存命中率下降 |
| 把用户身份混进 URL | 同一地址对不同人内容不同,必须靠协商字段区分缓存 |
容易混淆的点
- 网页打不开与接口返回 404 是两回事:前者多见于网络层与解析问题,后者说明请求已经到达服务器
- 只取头与取内容两个方法的差别仅在有没有响应体,语义与缓存判定规则完全一致
- 携带请求体的读取请求不是标准做法,部分网关与缓存会直接忽略或拒绝,不要依赖它