游乐游手机版
首页/前端开发/文章详情

Next.js 应用中不同域名差异化路由配置方法

时间:2026-07-23 20:12
通过Next js中间件获取请求域名,结合Host头动态控制路由可见性,可实现同一套代码在多个域名下展示差异化页面,如仅主域名显示 about,其他域名重定向或隐藏,有效支持多品牌站点场景。
通过 Next.js 中间件(Middleware)根据请求的 Host 头动态控制页面可见性,可实现在同一应用内为多个域名呈现不同路由配置——例如,仅在 something.com 显示 /about 页面,而在 somethingelse.com 中则隐藏或重定向该页面。

同一个 Next.js 应用,仅部署一套代码,却需要在不同域名下展示差异化的路由——比如主站 something.com 需要完整的 /about 内容页面,而落地页 somethingelse.com 只希望保留首页和登录入口,将 /about 隐藏起来。这类需求在 SaaS 多品牌或多站点场景中相当普遍,而 Next.js 中间件正是解决这一问题的理想工具。

在 Next.js 13+(App Router)中,中间件在请求到达服务端组件之前执行,是一个轻量级的路由拦截层。在此处,你可以获取请求的域名、路径,然后决定是放行、重定向还是直接返回 404。这样一来,一套代码就能同时服务于多个域名,主站和落地页各取所需,核心逻辑(如登录态、API 调用等)仍可复用,无需维护多套代码或部署多个实例。

✅ 实现原理:基于 Host 的条件路由控制

中间件运行在边缘环境(Edge Runtime),通过 request.headers.get('host') 获取当前请求的域名,再结合 request.nextUrl.pathname 判断路径,即可做出差异化的路由决策。

下面是一个可直接用于生产环境的示例代码:

// src/middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  const host = request.headers.get('host')?.toLowerCase() || '';
  const pathname = request.nextUrl.pathname;

  // 定义域名白名单策略
  const isMainDomain = host === 'something.com' || host.endsWith('.something.com');
  const isLandingDomain = host === 'somethingelse.com' || host.endsWith('.somethingelse.com');

  // /about 仅对主域名开放,其他域名重定向至首页
  if (pathname.startsWith('/about')) {
    if (!isMainDomain) {
      return NextResponse.redirect(new URL('/', request.url));
    }
  }

  // 可扩展:/admin 仅限内部域名访问
  if (pathname.startsWith('/admin') && !host.includes('internal.')) {
    return NextResponse.rewrite(new URL('/404', request.url));
  }

  // 允许所有其他请求继续
  return NextResponse.next();
}

// 指定中间件生效路径(支持 glob 匹配)
export const config = {
  matcher: [
    '/about/:path*',
    '/admin/:path*',
    // 注意:若需拦截根路径或动态路由,也应显式列出
  ],
};

⚠️ 关键注意事项

  • matcher 必须显式声明:中间件不会自动匹配所有路径,只有列在 matcher 里的路径才会触发这段逻辑。根路径或者动态路由如果也需要拦截,一定记得加入列表。
  • Host 头校验要细致:不要只写 host === 'somethingelse.com',万一出现子域名 xxx.somethingelse.com 就会遗漏。建议使用 endsWith() 或正则表达式,同时注意将 host 转为小写后比较,以避免大小写不匹配问题。
  • 小心循环重定向:重定向的目标路径(比如 /)本身不能出现在 matcher 列表里,否则会造成无限跳转。可以在逻辑中增加排除判断。
  • 静态生成(SSG)页面不受中间件影响:中间件仅对服务端渲染(SSR)或动态路由的请求生效。如果某个页面(如 app/about/page.tsx)被预渲染为静态 HTML,它将直接通过 CDN 缓存返回,中间件根本无法介入。因此,若希望路由始终走服务端渲染,记得配合 generateStaticParams: falsedynamic = 'force-dynamic'
  • NX 单体仓库里的位置:如果项目是 NX monorepo,请确保 middleware.ts 放在 Next.js 应用的 src/ 根目录下,而不是 workspace 根目录。同时检查构建配置是否正确识别了中间件入口。

✅ 进阶建议

  • 如果权限控制更为复杂(比如既要依据域名,又要根据用户角色),可以在中间件中调用 auth 服务验证会话,再做出决策。
  • 对于 SEO 敏感的页面(如 /about),建议对非授权域名返回 404(使用 NextResponse.next() 配合自定义 notFound()),而不是重定向到首页。这样搜索引擎不会收录错误路径。
  • 结合 next.config.js 中的 images.domainsheaders 配置,统一管理跨域资源策略,使方案更完善。

通过中间件驱动的域名级路由治理,你就能用一套代码、一个部署,安全灵活地复用核心逻辑,同时满足不同品牌站点的业务隔离需求,既省心又省力。

来源:https://www.php.cn/faq/2803561.html
上一篇Firefox扩展执行机制:运行时机与跨标签页通信 下一篇Highcharts Dumbbell图表多数据点悬停提示失效详细解决方法
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
JavaScript数组字面量与构造函数创建稀疏数组的差异
前端开发 · 2026-07-25

JavaScript数组字面量与构造函数创建稀疏数组的差异

数组字面量创建稠密数组,空位默认为undefined;Array()构造函数传入单个数字参数会生成稀疏数组,索引不存在且遍历方法跳过,多参数或非数字参数则行为与字面量一致。初始化稠密数组应使用Array from或fill。

如何优化Bootstrap按钮的焦点状态环CSS样式方法详解
前端开发 · 2026-07-25

如何优化Bootstrap按钮的焦点状态环CSS样式方法详解

Bootstrap按钮焦点样式优化需将内阴影改为外发光,覆盖所有焦点选择器避免原生蓝边闪烁。使用:focus-visible区分键盘与鼠标交互,同时处理按钮组圆角、父容器溢出及浏览器兼容性,确保焦点反馈清晰且符合无障碍标准。

Less中强制转换CSS单位适配不同移动端方案详解
前端开发 · 2026-07-25

Less中强制转换CSS单位适配不同移动端方案详解

Less单位转换需手动完成:用unit()剥离单位,通过变量控制基准值,再拼接目标单位。px2rem函数须区分输入类型(纯数字、带px单位等),基准值@base-font-size需全局定义且不可在媒体查询中重定义。所有运算发生在编译期,适配需提前编译多套CSS文件。

Vue 插件开发与使用完整指南
前端开发 · 2026-07-25

Vue 插件开发与使用完整指南

Vue插件通过install方法为应用注入全局属性、组件、指令、混入和provide等扩展能力,注册时机须在createApp之后、mount之前。插件支持对象或函数形式,使用app use()注册。开发时需注意命名冲突、配置默认值及错误处理,确保工程健壮性。

CSS响应式视频全屏黑边排版问题解决方案
前端开发 · 2026-07-25

CSS响应式视频全屏黑边排版问题解决方案

CSS响应式视频全屏黑边源于盒子模型、定位与加载策略缺失。需重置body边距及溢出,父容器用position:fixed与100dvh,video设为block+object-fit:cover。autoplay需加muted、playsinline。移动端用100dvh防地址栏抖动,低端机分辨率不超1倍。