HTTPQUERY
English

408 Request Timeout

用法

收到 408 Request Timeout 错误时,客户端已发起请求,但出于某种原因未能传输完整的载荷。这在互联网连接缓慢或已断开时发生。响应中包含 Connection 头,表明连接已被关闭。

在收到 Connection: close 头后,客户端会再次尝试请求。

注意

408 Request Timeout 意味着客户端向服务器发送请求太慢。504 Gateway Timeout 意味着代理或网关在等待后端服务器响应时超时。408 是客户端到服务器的超时,而 504 是服务器到服务器的超时。408 是少数值得自动重试的 4xx 状态码之一,因为其成因通常是瞬时的。

SEO 影响

像 Google 这样的搜索引擎不会索引返回 408 状态的 URL。此前已被索引、如今返回该状态码的 URL 会从搜索结果中移除。

示例

客户端开始向服务器发送一个 10K 的 PDF 文件,但连接遭遇间歇性的连通性问题,服务器判定传输过慢。服务器取消请求并关闭连接。当连接稳定后,客户端成功重新传输该文件。

初始请求

PUT /docs HTTP/1.1
Host: example.com
Content-Type: application/pdf
Content-Length: 10000

初始响应

HTTP/1.1 408 Request Timeout
Connection: Close
Content-Type: text/html
Content-Length: 198

<html>
  <head>
    <title>Connection Close</title>
  </head>
  <body>
    <p>The transmission was not received quickly
    enough. Check connectivity and try again.</p>
  </body>
</html>

下一次请求

PUT /docs HTTP/1.1
Host: example.com
Content-Type: application/pdf
Content-Length: 10000

<File transfer successful for PDF file>

最终响应

HTTP/1.1 200 OK

如何修复

408 Request Timeout 意味着服务器因客户端未能及时完成请求而关闭了连接。

检查网络连通性和延迟。不稳定或缓慢的连接会延迟请求传输。对服务器运行 ping 和 traceroute,以识别丢包或高延迟的跳数。在重试前确认连接稳定。

减小载荷大小或拆分大型上传。通过缓慢的连接发送大文件会超出服务器的耐心。压缩载荷、使用分块 Transfer-Encoding,或使用分片上传 API 将上传拆分为更小的部分。

增大客户端侧的超时设置。HTTP 客户端库或浏览器会强制执行自己的超时。调高连接和读取超时值以适应更慢的传输。在 curl 中,使用 —connect-timeout 和 —max-time。在 Python requests 中,设置 timeout=(connect, read)。

核实服务器的超时配置。根据 Web 服务器调整超时指令:

nginx:

client_header_timeout 60s;
client_body_timeout 60s;
keepalive_timeout 75s;
send_timeout 60s;

Apache:

Timeout 60
KeepAliveTimeout 5
RequestReadTimeout header=20-40 body=20

RequestReadTimeout 指令(mod_reqtimeout)分别控制头和消息体的读取超时。当客户端确实需要更多时间时,增大这些值。

调整 Keep-Alive 设置。过低的 keepalive_timeout 会在客户端在持久连接中发送下一个请求之前关闭空闲连接。在 nginx 中,keepalive_timeout 默认为 75 秒。为服务突发式请求模式客户端的 API 调高该值。在 Apache 中,增大 KeepAliveTimeout(默认 5 秒),并核实 MaxKeepAliveRequests 允许每个连接有足够多的请求。

检查反向代理和负载均衡器的超时。当反向代理(nginx、HAProxy、AWS ELB)位于应用服务器前面时,每一层都会强制执行自己的超时。如果代理的超时比后端短,代理会先关闭连接。在 nginx 反向代理模式下:

proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;

AWS ALB 的默认空闲超时为 60 秒,可在负载均衡器属性中配置。

重试请求。408 通常是瞬时的。重新建立连接并重新提交完整请求。为编程式客户端实现带指数退避的自动重试逻辑。当存在 Retry-After 头时,它指定了重试前的等待时长。

审查服务器错误日志。nginx 在错误日志中记录超时事件。Apache 记录 mod_reqtimeout 违规。检查 /var/log/nginx/error.log 或 /var/log/apache2/error.log 中与请求时间戳匹配的条目,以判断是头还是消息体读取超时。

代码参考

.NET

HttpStatusCode.RequestTimeout

Rust

http::StatusCode::REQUEST_TIMEOUT

Rails

:request_timeout

Go

http.StatusRequestTimeout

Symfony

Response::HTTP_REQUEST_TIMEOUT

Python3.5+

http.HTTPStatus.REQUEST_TIMEOUT

Java

java.net.HttpURLConnection.HTTP_CLIENT_TIMEOUT

Apache HttpComponents Core

org.apache.hc.core5.http.HttpStatus.SC_REQUEST_TIMEOUT

Angular

@angular/common/http/HttpStatusCode.RequestTimeout