Vercel Edge Functions本地正常 生产环境使用hostname-rewrites返回404求助
解决方案
1. 修正hostname获取逻辑
你当前使用req.headers.get('host')获取域名,生产环境该值可能携带端口号(比如yourdomain.com:443),直接拼接进路径会导致路由匹配失败。改用Next.js封装的属性获取纯域名:
将代码中let hostname = req.headers.get('host')替换为const hostname = req.nextUrl.hostname
2. 适配动态路由的全路径匹配
你当前的目录结构/pages/_sites/[sites]/index.js仅能匹配/_sites/xxx/根路径,无法匹配/_sites/xxx/foo/bar这类子路径,需要改为捕获所有的动态路由:
- 将
/pages/_sites/[sites]文件夹重命名为/pages/_sites/[...sites] - 原
index.js保留在[...sites]文件夹下即可,支持匹配所有/_sites/*前缀的路径
3. 兼容i18n国际化路径处理
如果你开启了Next.js i18n功能,req.nextUrl.pathname会自动携带locale前缀(比如/zh-CN/about),需要先剥离前缀再拼接路径。同时补充middleware默认返回逻辑,部分Next.js版本无明确返回值会直接返回404:
import { NextResponse } from 'next/server' export default function middleware(req) { const { pathname, locale } = req.nextUrl const hostname = req.nextUrl.hostname // 剥离locale前缀 const purePathname = locale ? pathname.replace(`/${locale}`, '') : pathname if ( !purePathname.includes('.') && !purePathname.startsWith('/api') ) { if ( !hostname.includes('example.vercel.app') && hostname !== 'example.com' && hostname !== 'localhost' ) { return NextResponse.rewrite(`/_sites/${hostname}${purePathname}`) } } // 未匹配规则时正常返回 return NextResponse.next() }
4. 补充生产环境配置
在项目根目录新建vercel.json文件,确保边缘函数优先级高于静态路由匹配:
{ "rewrites": [ { "source": "/:path*", "has": [{ "type": "host", "value": "(?<host>.*)" }], "destination": "/:path*" } ], "cleanUrls": true }
额外注意:需要在Vercel控制台的项目域名设置中,将你用到的所有自定义域名都添加到域名列表,否则Vercel会直接拦截请求返回404,不会执行边缘函数逻辑。
内容的提问来源于stack exchange,提问作者Avichay Dahan
相关产品推荐
相关产品推荐

