Next.js Rewrite配置引发ERR_SSL_PROTOCOL_ERROR问题求助
解决Next.js中间件生产环境SSL协议错误(ERR_SSL_PROTOCOL_ERROR)
问题背景
使用Next.js中间件将/_site/[siteUrl]页面重写为[siteUrl].domain.com的多租户模式,本地运行正常,但部署到Vercel生产环境后,访问子域名页面出现ERR_SSL_PROTOCOL_ERROR,提示子域名(如a.****.vercel.app)无法提供安全连接。
可能原因及解决步骤
1. 未正确配置Vercel通配符子域名
Vercel不会自动为任意子域名生成SSL证书,必须在项目控制台手动添加通配符子域名:
- 进入Vercel项目的「Settings」→「Domains」
- 添加
*.your-team-slug.vercel.app(替换成你的团队slug)或者自定义域名的通配符(如*.yourdomain.com) - 等待Vercel自动生成通配符SSL证书(通常需要1-5分钟,状态显示「Issued」即为生效)
2. 环境变量NEXT_PUBLIC_DOMAIN配置错误
生产环境下该变量必须准确设置为你的根域名:
- 如果用Vercel自带域名,设为
your-team-slug.vercel.app - 如果用自定义域名,设为
yourdomain.com - 确保变量在Vercel控制台的「Settings」→「Environment Variables」中正确配置,且勾选了「Production」环境
3. 中间件中currentHost解析逻辑存在问题
原代码的两次replace可能导致解析错误,建议改用正则表达式统一处理后缀,避免顺序冲突:
export default async function middleware(req: NextRequest) { const url = req.nextUrl; const hostname = req.headers.get('host') ?? ``; const path = url.pathname; const currentHost = process.env.NODE_ENV === 'production' && process.env.VERCEL === '1' // 用正则一次性匹配并替换vercel.pub和自定义域名后缀 ? hostname.replace(new RegExp(`\\.(vercel\\.pub|${process.env.NEXT_PUBLIC_DOMAIN?.replace(/\./g, '\\.')})$`), '') : hostname.replace(`.localhost:3000`, ''); // 根域名直接返回原路径 if (hostname === 'localhost:3000' || hostname === process.env.NEXT_PUBLIC_DOMAIN) { return NextResponse.rewrite(new URL(path, req.url)); } // 子域名重写到对应站点路径 return NextResponse.rewrite(new URL(`/_sites/${currentHost}${path}`, req.url)); }
4. SSL证书未生效或存在冲突
- 检查Vercel域名页面的SSL状态,若显示「Pending」,等待几分钟或重新触发证书生成(删除域名后重新添加)
- 确保没有同时配置多个冲突的域名解析(比如自定义域名和Vercel域名同时指向项目)
5. 验证重写逻辑正确性
在Vercel控制台的「Functions」→「Middleware」日志中查看请求详情,打印关键参数确认解析是否正确:
// 在中间件开头添加日志 console.log('Hostname:', hostname); console.log('CurrentHost:', currentHost); console.log('Rewritten URL:', new URL(`/_sites/${currentHost}${path}`, req.url).toString());
确认currentHost没有为空或包含无效字符,重写后的路径是正确的内部路由,而非外部域名跳转。
内容的提问来源于stack exchange,提问作者Shreyas Jadhav
相关产品推荐
相关产品推荐

