You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 17:15:03