VitePress 中使用 Axios 请求 HTTPS 接口时报 “certificate has expired” 错误的解决方案

207 阅读2分钟

#vitepress

VitePress 中使用 Axios 请求 HTTPS 接口时报 “certificate has expired” 错误的解决方案

在使用 VitePress 构建文档网站时,尝试通过 axios 请求一个 HTTPS 接口(例如在页面组件中获取远程数据),却在构建或运行时遇到如下错误:

 cause: Error: certificate has expired
      at TLSSocket.onConnectSecure (node:_tls_wrap:1679:34)
      at TLSSocket.emit (node:events:507:28)
      at TLSSocket._finishInit (node:_tls_wrap:1078:8)
      at ssl.onhandshakedone (node:_tls_wrap:864:12) {
    code: 'CERT_HAS_EXPIRED'

这是 Node.js 环境下 axios 请求一个 HTTPS 接口时,对方的证书过期 导致的,常见于:

  • 使用旧的第三方服务接口
  • 请求公司内网接口(自签名证书)
  • 构建或预渲染阶段触发 HTTP 请求(如 VitePress 的 SSR)

✅ 问题定位关键点

  1. VitePress 是运行在 Node.js 环境中,使用 SSR(服务端渲染)预构建文档页面。
  2. 所以当你在 .md 或 theme 中的代码中写了类似:
import axios from 'axios'
axios.get('https://xxx.com/api/data')

会在 构建阶段执行,若目标接口证书过期,Node.js 默认会拒绝连接。

✅ 解决方案(按优先推荐顺序)

✅ 方案一: 避免 SSR 时发起请求

VitePress 会在构建时运行 SSR,如果你只想在浏览器中运行 axios 请求,必须用 onMounted 或 client-only 包裹。

VitePress 会在构建时运行 SSR,如果你只想在浏览器中运行 axios 请求,必须用 onMounted 或 client-only 包裹。

✅ 方法 1:用onMounted (推荐

<script setup>
import { onMounted, ref } from 'vue'
import axios from 'axios'

const data = ref(null)

onMounted(async () => {
  try {
    const res = await axios.get('https://xxx.com/api/data')
    data.value = res.data
  } catch (err) {
    console.error(err)
  }
})
</script>

✅ 这会让请求只在客户端浏览器中执行,避免 Node 处理 HTTPS 证书。


✅ 方案二:用 <ClientOnly>

包裹组件

<ClientOnly>
  <YourComponent />
</ClientOnly>

适用于你把 axios 请求写在 Vue 组件里时。


✅ 方案三:开发/构建阶段临时忽略证书(仅用于调试)

如果你确实需要在构建阶段请求 HTTPS 接口,但对方证书已过期或是自签名,你可以在顶层设置:

// vitepress/config.js 或你自定义的 node 脚本中
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'

或者 axios 局部配置:

import https from 'https'

const agent = new https.Agent({ rejectUnauthorized: false })

axios.get('https://xxx.com/api/data', { httpsAgent: agent })

⚠️ 强烈不建议生产环境使用此方式。


✅ 总结

场景解决方式
构建时 axios 请求失败避免 SSR 请求,放在 onMounted 中执行
证书过期但必须构建时访问使用 rejectUnauthorized: false 临时绕过
请求第三方/公司接口有证书问题搭建代理中转层解决