首页
/ Axios HTTP/2 实战指南:httpVersion 与 http2Options 配置详解及源码实现剖析

Axios HTTP/2 实战指南:httpVersion 与 http2Options 配置详解及源码实现剖析

2026-09-04 20:38:45作者:廉彬冶Miranda

本文围绕 Axios 的 HTTP/2 实验性支持展开(Node.js 环境专用,v1.13.0+ 引入),系统讲解 httpVersionhttp2Options 两个配置项的用法、默认值与限制,并结合 lib/adapters/http.jslib/helpers/Http2Sessions.js 的源码实现,说明会话池复用、空闲超时关闭(sessionTimeout)以及重定向、代理等不支持场景背后的真实调用链,帮助你在服务端场景中安全、高效地启用 HTTP/2 请求。

特性定位:实验性、仅限 Node.js

HTTP/2 的实验性支持是在 http 适配器(即 Node.js 端适配器)中于 v1.13.0 版本加入的,CHANGELOG 中记录了该特性条目(http: add HTTP2 support)。这意味着:

  • 仅在 Node.js 环境中可用。浏览器/React Native 构建中,打包器通过 browser 字段把 lib/adapters/http.js 替换为 lib/helpers/null.js,HTTP/2 代码路径永远不会被执行(见 lib/helpers/Http2Sessions.js 顶部的注释说明);
  • 该特性仍标记为 Experimental,官方文档明确提示:API 可能在未来的次要或补丁版本中发生变化。

基本用法:httpVersion 选择协议版本

使用 httpVersion 选项为单次请求选择协议版本,将其设置为 2 即启用 HTTP/2:

const { data, headers, status } = await axios.post(
  "https://httpbin.org/post",
  form,
  {
    httpVersion: 2,
  },
);

httpVersion 的默认值是 1(HTTP/1.x)。从 TypeScript 类型定义看,该字段被约束为 1 | 2 的联合字面量类型(见 index.d.ts):

httpVersion?: 1 | 2;
http2Options?: Record<string, any> & {
  sessionTimeout?: number;
};

lib/adapters/http.js 中,适配器对 httpVersion 做了严格的运行时校验:

  1. 未显式提供时回退为 1
  2. 先做 +httpVersion 数值化转换,若结果不是数字(Number.isNaN),抛出 TypeError: Invalid protocol version: '...' is not a number
  3. 若非 12,抛出 TypeError: Unsupported protocol version '...'
  4. 最终通过 const isHttp2 = httpVersion === 2 决定走哪条传输通道。

http2Options:透传原生选项与 sessionTimeout

http2Options 配置对象用于向内部的 session.request() 调用透传 Node.js 内置 http2 模块支持的原生选项,其中包括一个 axios 自定义参数 sessionTimeout,控制空闲 HTTP/2 会话在被关闭前保活多久(单位毫秒),默认值为 1000ms

{
  httpVersion: 2,
  http2Options: {
    rejectUnauthorized: false, // 接受自签名证书(仅限开发环境)
    sessionTimeout: 5000,       // 空闲会话保活 5 秒
  },
}

sessionTimeout 的源码实现

sessionTimeout 的行为由 lib/helpers/Http2Sessions.js 实现,核心逻辑如下:

  • 默认值注入getSession(authority, options) 会用 Object.assign{ sessionTimeout: 1000 } 与传入选项合并,未传时即得到默认的 1000ms(对应 Http2Sessions.js#L16-L23);
  • 包装 request 方法:当 sessionTimeout != null 时,实现会对 session.request 做一层包装,用 streamsCount 跟踪打开中的流。每次新请求会清除待触发的空闲定时器;当某个流触发 close 事件后,只有当计数归零(即没有任何在途流)时才启动 setTimeout(sessionTimeout) 的关闭计时(见 Http2Sessions.js#L80-L106);
  • 计时到期自动回收:定时器触发后执行 removeSession()——从池中移除该 authority 的会话条目、清除定时器,并在会话未关闭时调用 session.close(),防止空闲连接长期占用资源;
  • 异常自愈:会话的 close / error 事件都会触发 removeSession(),失败的会话不会残留在池中;且会话真正关闭时会主动 clearTimeout,避免定时器在无谓地延长 Node 事件循环的存活时间。

这些行为均有直接对应的单元测试覆盖,例如 tests/unit/helpers/Http2Sessions.test.js 验证了:

  • 相同 authority 与相同选项会复用同一缓存会话(http2.connect 只调用一次);
  • 不同 authority、或相同 authority 但选项不同(如 sessionTimeout: 1000 vs 5000)会各自建立独立会话;
  • destroyed / closed / 触发过 closeerror 事件的会话不会被复用;
  • 最后一个流结束后经过 sessionTimeout 才关闭会话;新流打开会取消待触发的空闲定时器;仍有流打开时不关闭;
  • 不传选项时默认 sessionTimeout1000ms(999ms 不关闭、到 1000ms 关闭);sessionTimeout: null 时不安装 request 包装器。

会话池与请求流程

Http2Sessions 实例在 lib/adapters/http.js 中作为模块级单例创建(const http2Sessions = new Http2Sessions()),为进程内所有 HTTP/2 请求提供会话复用。http2Transport.request() 的处理流程(见 http.js#L511-L557):

  1. 构造 authority:按 protocol://hostname:port 拼接(https 缺省端口 443,http 缺省 80),作为会话池的缓存键;
  2. 获取会话http2Sessions.getSession(authority, http2Options),同 authority 且选项深相等(util.isDeepStrictEqual)的存活会话直接复用;
  3. 映射伪头(pseudo-headers):HTTP/2 要求用 :scheme:method:path 伪头描述请求,适配器从 axios 的 options 中提取并写入,然后把除伪头外的普通请求头逐一复制到 http2Headers
  4. 发起请求session.request(http2Headers) 得到双向流 req;监听 response 事件,把 :status 伪头取出转为 response.statusCode,其余响应头放入 response.headers,随后回调给上层走统一的 settle/数据解析流程。

此外,适配器在构造请求选项时,如果同时配置了 lookup 函数,会将其合并进 http2OptionsObject.assign(Object.create(null), http2Options, { lookup }),见 http.js#L925-L927),使自定义 DNS 解析在 HTTP/2 路径下同样生效。

完整示例:multipart 上传 + 进度跟踪

下面的示例通过 HTTP/2 发送 multipart/form-data POST 请求,并同时跟踪上传与下载进度(来自 docs/es/pages/advanced/http2.md 的完整示例):

const form = new FormData();
form.append("foo", "123");

const { data, headers, status } = await axios.post(
  "https://httpbin.org/post",
  form,
  {
    httpVersion: 2,
    http2Options: {
      // rejectUnauthorized: false,
      // sessionTimeout: 1000
    },
    onUploadProgress(e) {
      console.log("upload progress", e);
    },
    onDownloadProgress(e) {
      console.log("download progress", e);
    },
    responseType: "arraybuffer",
  },
);

注意两点:

  • onUploadProgress / onDownloadProgress 回调在 HTTP/2 传输下与 HTTP/1.x 行为一致,可直接复用现有的进度展示逻辑;
  • 示例中 http2Options 的字段以注释形式给出,说明这两项都是可选的——不传时 sessionTimeout 取默认 1000ms,TLS 校验保持 Node.js 默认行为。

限制与注意事项

重定向不被支持

HTTP/2 适配器目前不会自动跟随重定向:使用 httpVersion: 2 发出的请求若收到 3xx 响应,axios 不会像 HTTP/1.x 路径(基于 follow-redirects 传输)那样继续请求新地址。对此有两种处理方式:

  • 在业务代码中手动处理 3xx 响应,自行发起后续请求;
  • 对依赖重定向的端点,保持 httpVersion: 1(或不设置)走 HTTP/1.x。

这一点与源码结构一致:HTTP/1.x 路径在 maxRedirects !== 0 时会选用支持重定向跟随的传输并注入 beforeRedirects 逻辑,而 isHttp2 分支直接选用 http2Transport,不存在重定向跟随逻辑(见 http.js#L1012-L1033)。

代理不被支持

从源码看,HTTP/2 传输独立于 HTTP/1 的 agent 建立连接,无法应用 axios 解析的环境代理或 agent 级代理。因此当请求同时满足 isHttp2 且检测到代理已生效(proxyApplied)时,适配器会直接以 AxiosError.ERR_NOT_SUPPORT 拒绝请求,错误信息为 HTTP/2 requests with a proxy are not supported(见 http.js#L1012-L1021)。需要经代理访问的 HTTP/2 端点请保留 HTTP/1.x。

实验性声明

HTTP/2 支持当前仍为实验性,API 可能在未来版本中调整;生产环境引入前建议锁定 axios 版本并关注后续版本说明。

配置参考

选项 类型 默认值 说明
httpVersion number 1 要使用的 HTTP 协议版本。设为 2 启用 HTTP/2。仅接受 12,非法值会抛出 TypeError
http2Options.sessionTimeout number 1000 空闲 HTTP/2 会话在关闭前的保活时间(毫秒)。最后一个流结束后开始计时;新流打开会重置计时;设为 null 可关闭自动回收。

http2Options 内还可以传递 Node.js 内置 http2 模块支持的其它原生 session.request() 选项(例如 rejectUnauthorized 等 TLS 相关参数)。注意:由于会话复用要求选项深度相等才会命中缓存,同一 authority 下传入不同的 http2Options(如不同的 sessionTimeout 或 TLS 参数)会建立各自独立的 HTTP/2 会话,这是 tests/unit/helpers/Http2Sessions.test.js 中"creates a new session when options differ for the same authority"用例所验证的行为。

相关源码与测试索引

位置 内容
docs/es/pages/advanced/http2.md(及 英文版 本文对应的官方 HTTP/2 文档
lib/adapters/http.js http2Transport:authority 构造、伪头映射与响应解析
lib/adapters/http.js httpVersion 校验与 isHttp2 分流
lib/helpers/Http2Sessions.js 会话池:复用判定、sessionTimeout 空闲回收、错误自愈
tests/unit/helpers/Http2Sessions.test.js 会话池行为的单元测试(复用、超时、清理、默认值)
index.d.ts httpVersion / http2Options 的 TypeScript 类型定义
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
980
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384