308 Permanent Redirect
用法
收到 308 Permanent Redirect 状态码时,客户端应当将已存储的链接更新为新的 URI。新的 URI 由 Location 头指定,客户端据此进行自动重定向。
当服务器迁移到新域名,或在没有计划恢复到旧 URI 的情况下重新组织其内部文件结构时,通常会返回此响应。
308 Permanent Redirect 状态码在一个关键点上不同于 301:客户端必须保留原始请求方法。301 响应允许客户端在重定向时将 POST 请求改为 GET 请求。而 308 Permanent Redirect 要求后续请求使用与原始请求相同的方法。这使得 308 成为方法保留至关重要场景(如 API 端点和表单提交)下的正确选择。308 状态码最初被定义为一个独立规范,之后才并入 HTTP 核心标准。
SEO 影响
Google 对 308 的处理与 301 完全相同。二者都是永久重定向,都是重定向目标即为规范 URL 的强信号。排名信号会从旧 URL 转移到新 URL。Google 最多跟随 10 跳重定向。中间重定向 URL 的内容会被忽略。301 与 308 唯一的区别在于方法保留,这对 API 端点有意义,但对搜索引擎抓取无关紧要。用 308 将已删除的 URL 重定向到首页或通用分类页,会被 Google 判定为软 404。
示例
客户端向某个 API 端点提交 POST 请求。服务器返回 308 Permanent Redirect,表明该端点已移动。客户端必须在新 Location 处重复该 POST 请求,包括原始消息体。
请求
POST /api/v1/orders HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 35
{"item": "widget", "quantity": 10}
响应
HTTP/1.1 308 Permanent Redirect
Location: http://example.com/api/v2/orders
Content-Type: text/html; charset=UTF-8
Content-Length: 118
<h1>API endpoint moved</h1>
<body>
The orders endpoint has moved to
<a href=/api/v2/orders>/api/v2/orders</a>.
</body>
代码参考
.NET
HttpStatusCode.PermanentRedirect
Rust
http::StatusCode::PERMANENT_REDIRECT
Rails
:permanent_redirect
Go
http.StatusPermanentRedirect
Symfony
Response::HTTP_PERMANENTLY_REDIRECT
Python3.5+
http.HTTPStatus.PERMANENT_REDIRECT
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_PERMANENT_REDIRECT
Angular
@angular/common/http/HttpStatusCode.PermanentRedirect