426 Upgrade Required
用法
收到 426 Upgrade Required 状态码时,响应中会包含一个 Upgrade 响应头字段,指明所需的协议。
此消息与 101 Switching Protocols 消息相关,后者是服务器对客户端使用 Upgrade 头发起的协议升级请求所作的响应。
SEO 影响
像 Google 这样的搜索引擎不会索引返回 426 状态的 URL。过去已被索引但返回此状态码的 URL 会从搜索结果中移除。
示例
客户端通过明文 HTTP 请求某个资源,服务器返回 426 Upgrade Required,因为 TLS 是强制要求的。客户端切换到 HTTPS 后请求成功。
HTTP/2 和 HTTP/3
HTTP/2 和 HTTP/3 是在 TLS 握手期间通过 ALPN 协商的,而不是通过 Upgrade 头。明文 HTTP/2 升级机制(h2c)已从规范中移除。Upgrade 头适用于诸如 TLS 和 WebSocket 之类的协议切换。
初始请求
GET /tech-news HTTP/1.1
Host: example.com
初始响应
HTTP/1.1 426 Upgrade Required
Upgrade: TLS/1.2
Connection: upgrade
Content-Type: text/html
Content-Length: 140
<html>
<head>
<title>TLS Required</title>
</head>
<body>
<p>This service requires TLS.</p>
</body>
</html>
通过 HTTPS 发起的后续请求
GET /tech-news HTTP/1.1
Host: example.com
响应
HTTP/1.1 200 OK
Content-Type: text/html
如何修复
读取响应中的 Upgrade 头以确定所需的协议。服务器会列出一个或多个可接受的协议,例如 TLS/1.2、HTTP/2、HTTP/3 或 websocket。
对于协议版本升级,将客户端切换到指定协议并重新发送请求。HTTP/2 和 HTTP/3 在 TLS 握手期间使用 ALPN,而非 Upgrade 头。对于 WebSocket 等其他协议,请包含 Connection: upgrade 和相匹配的 Upgrade 头。服务器会返回 101 Switching Protocols,随后连接在新协议下继续。
对于通过 nginx 建立的 WebSocket 连接,配置代理以转发 upgrade 头:
若缺少这些指令,nginx 会对上游连接默认使用 HTTP/1.0 并剥离 upgrade 头,从而在每次 WebSocket 握手尝试时返回 426。
当服务器强制要求 HTTPS 时,将请求 URL 的方案从 http:// 改为 https://。确认客户端或运行时环境启用了 TLS 1.2 或 TLS 1.3。较旧的 TLS 版本通常会被拒绝。
当客户端库和 SDK 不支持所需协议时,请更新它们。过时的 HTTP 库默认使用 HTTP/1.1,不具备 HTTP/2 或 HTTP/3 协商能力。
从并非用于协议切换的请求中移除多余的 Upgrade 头。有些代理会把一个多余的 Upgrade 头解读为协议协商尝试并返回 426。
代码参考
.NET
HttpStatusCode.UpgradeRequired
Rust
http::StatusCode::UPGRADE_REQUIRED
Rails
:upgrade_required
Go
http.StatusUpgradeRequired
Symfony
Response::HTTP_UPGRADE_REQUIRED
Python3.5+
http.HTTPStatus.UPGRADE_REQUIRED
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_UPGRADE_REQUIRED
Angular
@angular/common/http/HttpStatusCode.UpgradeRequired