解决Next.js API路由调用ASP.NET Core API的自签名证书错误
核心原因
浏览器已经信任了你配置的自签名证书,但Next.js的API路由运行在Node.js服务端环境,Node.js的证书信任池和Windows系统的证书存储并不完全同步,所以服务端发起的fetch请求会出现证书验证失败的错误,而前端浏览器的fetch请求则能正常工作。
本地开发环境的简单解决方案
方案1:临时禁用Node.js证书验证(仅开发环境使用)
这是最快的临时解决方式,适合本地开发测试,绝对不要在生产环境使用。
- 方式一:在API路由中单独配置
在你的/api/endpoint.js文件中,给fetch请求添加自定义HTTPS代理,关闭证书验证:
import { NextResponse } from 'next/server'; import https from 'https'; export async function GET() { // 创建禁用证书验证的HTTPS代理 const agent = new https.Agent({ rejectUnauthorized: false }); const res = await fetch('https://localhost:7001/endpoint', { agent }); const data = await res.json(); return NextResponse.json(data); }
- 方式二:通过环境变量全局禁用
启动Next.js时设置环境变量,让Node.js跳过所有HTTPS证书验证:- Windows CMD:
set NODE_TLS_REJECT_UNAUTHORIZED=0 && npm run dev - Windows PowerShell:
$env:NODE_TLS_REJECT_UNAUTHORIZED=0; npm run dev - Linux/macOS:
NODE_TLS_REJECT_UNAUTHORIZED=0 npm run dev
- Windows CMD:
方案2:将.NET Core开发证书导入Node.js信任链
如果不想禁用证书验证,可以把.NET Core的开发证书添加到Node.js的信任列表中:
- 导出.NET Core开发证书为PEM格式
先找到.NET Core生成的证书文件,默认路径是%USERPROFILE%\.aspnet\https,里面有localhost.pfx文件。使用OpenSSL将其导出为PEM格式:
openssl pkcs12 -in "%USERPROFILE%\.aspnet\https\localhost.pfx" -nokeys -out localhost.pem -passin pass:
(注:如果导出时提示密码错误,先重新生成带密码的证书:dotnet dev-certs https -ep "%USERPROFILE%\.aspnet\https\localhost.pfx" -p "your-password",然后导出时把-passin pass:改成-passin pass:your-password)
- 在API路由中指定信任该证书
将导出的localhost.pem放到Next.js项目根目录,然后在API路由中配置fetch使用该证书:
import { NextResponse } from 'next/server'; import https from 'https'; import fs from 'fs'; export async function GET() { // 读取本地PEM证书文件 const caCert = fs.readFileSync('./localhost.pem', 'utf8'); const agent = new https.Agent({ ca: caCert }); const res = await fetch('https://localhost:7001/endpoint', { agent }); const data = await res.json(); return NextResponse.json(data); }
你的疑问解答
是否需要将Next.js应用运行在HTTPS?
不需要,当前问题的根源不是Next.js前端的协议,而是服务端fetch请求的Node环境不信任证书。如果后续有Cookie的Secure属性要求等场景,可以考虑启用HTTPS,但不是解决当前问题的必要操作。是否因为Next.js的/api路由非安全URL?
不是,/api路由是运行在服务端的逻辑,和前端的HTTP/HTTPS协议无关,问题出在服务端请求目标HTTPS接口时,Node.js不认可自签名证书。Next.js为何默认不启用HTTPS?
开发环境默认使用HTTP是为了降低开发复杂度,启用HTTPS需要额外配置证书、端口等,官方将这个选择权交给开发者,根据实际需求自行配置。
内容的提问来源于stack exchange,提问作者Tristan Trainer

