You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Axios HEAD请求莫名超时排查:跨机器表现差异及工具兼容问题

问题:Axios HEAD请求在部分机器超时,curl正常的排查方案

背景信息

我尝试用Axios发送HEAD请求,获取目标文件的Last-Modified响应头,目标文件地址:
http://daten-hamburg.de/opendata/3d_stadtmodell_lod2/LoD2-DE_HH_2023-04-01.zip

使用的Axios重试配置和获取函数如下:

axiosRetry(axios, {
  retries: 10,
  retryDelay: axiosRetry.exponentialDelay,
  onRetry: (retryCount, error, requestConfig) => {
    log.warn(`Retry attempt #${retryCount} for ${requestConfig.url}`)
  },
})

export const getlastModified = async (url: string) => {
  try {
    const response = await axios.head(url, {
      timeout: 20000,
    }) // 20秒超时
    const lastModified = response.headers['last-modified']
    log.debug(response.headers)
    const date = new Date(lastModified)
    return date
  } catch (error) {
    console.error(`Error fetching headers: ${error}`)
    return undefined
  }
}

两台机器的依赖版本完全一致:

"axios": "^1.7.7",
"axios-retry": "^4.5.0",

异常现象

  • 代码在一台机器上正常运行,但在另一台网络更快的机器上持续超时
  • 两台机器执行curl -I http://daten-hamburg.de/opendata/3d_stadtmodell_lod2/LoD2-DE_HH_2023-04-01.zip均能正常返回响应头
  • 额外发现:curl可以下载该文件,但wget连接服务器时会挂起

排查步骤建议

1. 对比两台机器的HTTP请求细节

在两台机器上分别执行curl -v -I <目标URL>,对比输出的请求头、协商的HTTP版本、SSL/TLS版本,重点关注:

  • Axios默认可能使用HTTP/2,而curl默认用HTTP/1.1,目标服务器可能对HTTP/2兼容性有问题
  • 检查请求头中的User-Agent,Axios的默认UA和curl不同,服务器可能对特定UA做了限流或拦截

2. 强制Axios使用HTTP/1.1

修改Axios配置,禁用HTTP/2,模拟curl的行为:

const http = require('http');
const https = require('https');

// 在请求中添加配置
const response = await axios.head(url, {
  timeout: 20000,
  httpAgent: new http.Agent({ keepAlive: false }),
  httpsAgent: new https.Agent({ keepAlive: false }),
  maxVersion: 'http/1.1'
})

3. 模拟curl的请求头

把curl的请求头完全复制到Axios中,尤其是User-Agent和Accept字段:

const response = await axios.head(url, {
  timeout: 20000,
  headers: {
    'User-Agent': 'curl/7.81.0', // 替换成你机器上curl的实际UA
    'Accept': '*/*'
  }
})

4. 检查机器网络环境差异

  • 检查防火墙、代理设置:网络更快的机器可能走了代理,而代理对HEAD请求处理有问题
  • 对比DNS解析结果:用nslookup daten-hamburg.de查看两台机器解析到的IP,可能其中一台指向了不稳定的节点
  • 抓包分析TCP连接:用tcpdump或Wireshark抓取超时机器的网络包,看TCP握手是否正常、是否有数据包丢失

5. 替换请求方法测试

尝试用GET请求替代HEAD,只获取响应头(不下载完整内容):

const response = await axios.get(url, {
  timeout: 20000,
  headers: { 'Range': 'bytes=0-0' }, // 仅请求第一个字节
  responseType: 'stream'
})
// 同样提取response.headers['last-modified']

6. 排查wget挂起的原因

在超时机器上执行wget -d <目标URL>,查看调试输出,重点看:

  • wget使用的HTTP版本、请求头
  • 是卡在TCP连接阶段,还是等待响应阶段
  • 这大概率和Axios的问题同源,比如服务器对HTTP/1.1持久连接的处理存在bug

内容的提问来源于stack exchange,提问作者pcace

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 09:05:07