303 是什么
303 See Other 让客户端「改用 GET 去访问另一个地址」取结果。它最典型的用法是表单提交后的跳转:POST 处理成功,服务器回 303 + Location,浏览器接着发一个 GET,于是刷新页面不会重复提交表单——这就是 POST/Redirect/GET(PRG)模式。303 的语义明确不保留原方法,这让它比 302 更适合做提交后的跳转。
基本信息
| 名称与状态码 | 303 See Other |
|---|---|
| 语义 | 用 GET 请求 Location 指定的资源 |
| 方法处理 | 明确改写为 GET,丢弃原请求体 |
| 规范 | RFC 9110 §15.4.4 |
| 典型场景 | 表单提交成功后的结果页跳转 |
| 响应头 | 必须带 Location |
典型使用场景
- 订单、注册、评论等表单提交成功后跳转到结果页,防止刷新重复提交
- 支付回跳:第三方支付完成后把用户送回商户的结果页
- 把写操作的响应体转成可收藏、可分享的 GET URL
- 旧版接口用 302 做提交跳转、被浏览器改写为 GET 造成语义混乱时改为 303
- HTTP 客户端按规范处理重定向:只有 303 可以放心地把方法改成 GET
PRG:提交后 303 跳转
PRG:提交后 303 跳转
# 第一步:提交表单(写操作)
POST /orders HTTP/1.1
Content-Type: application/x-www-form-urlencoded
# 第二步:服务端创建成功后返回 303 与目标地址
HTTP/1.1 303 See Other
Location: /orders/2026-1013-001
# 第三步:浏览器自动改用 GET 取结果页
GET /orders/2026-1013-001 → HTTP/1.1 200 OK重定向状态码对比
| 状态码 | 方法是否保留 | 典型用途 | 是否长期缓存 |
|---|---|---|---|
| 302 Found | 历史实现常被改写成 GET | 临时跳转 | 不缓存 |
| 303 See Other | 明确改成 GET | 提交后跳转结果页(PRG) | 不缓存 |
| 307 Temporary Redirect | 严格保留方法与请求体 | 临时跳转且不能改方法 | 不缓存 |
| 308 Permanent Redirect | 严格保留方法与请求体 | 永久跳转且不能改方法 | 浏览器长期缓存 |
303 与 307 常在同一个 PRG 方案里成对出现:处理 POST 成功后回 303 让客户端改 GET 去看结果;而需要原样重发请求体的场景(如跨域的 PUT 重定向)才用 307。
303 之后浏览器会带 Location 发起 GET,若该地址需要登录态或一次性令牌,会因为跨站跳转而丢失 Cookie(SameSite=Lax/Strict 场景),表现为「跳转后回到登录页」。