如何在代理后面服务器端的 Next.js v13 应用程序中从域重定向到另一个域

Pro*_*mek 3 proxy redirect middleware docker next.js

我确实有很多域,我想将它们重定向到一个主域。

域列表:

  • example.com
  • example1.com
  • example2.com
  • example3.com

我想从其他域重定向的主域是example.com

有一个很好的答案可以将服务器端的 Next.js 重定向到不同的路径。

Next.js >= 12现在您可以使用中间件进行重定向,在pages文件夹(或pages内的任何子文件夹)内创建一个_middleware.js文件

import { NextResponse, NextRequest } from 'next/server'
export async function middleware(req, ev) {
    const { pathname } = req.nextUrl
    if (pathname == '/') {
        return NextResponse.redirect('/hello-nextjs')
    }
    return NextResponse.next() } 
Run Code Online (Sandbox Code Playgroud)

来源:/sf/answers/4072787491/

注意:对于 Next.js v13,您必须middleware.js在 Next.js 的根目录中创建该文件,而不是像pages/_middleware.js该答案中提到的那样。

如果我尝试重定向到另一个域,根目录中的 middleware.ts 中的 TypeScript 代码如下所示:

/* eslint-disable @next/next/no-server-import-in-page */
import { NextResponse, NextRequest } from 'next/server'

export async function middleware(req: NextRequest) {
    const url = req.nextUrl.clone()
    console.log(url.host) //logs localhost:3000

    if (!url.host.match(/example.com/)) {
        url.host = 'example.com'
        return NextResponse.redirect(url) //never executes because the URL is always localhost in the Docker container
    }
    return NextResponse.next()
}
Run Code Online (Sandbox Code Playgroud)

但是,在代理服务器后面的 Docker 容器中运行的 Next.js v13 应用程序始终具有localhost主机中的 URL。在url.hostDocker 容器中,URL localhost 始终等于容器内定义的端口(例如localhost:3000)。

当我只在服务器端时,如何重定向域example1.com,example2.com并example3.com包括example.com相同的路径、查询参数和哈希?localhost

Pro*_*mek 10

如果要将Docker容器中的所有域重定向到master域,则需要从X-Forwarded-Host标头中获取重定向的URL。

除了主机之外,您还必须设置正确的端口(80/443 - 标头称为X-Forwarded-Port)和协议(http/https - 标头称为X-Forwarded-Proto)。

Next.js v13middleware.ts在应用程序的文件夹中创建文件src,并将生产中与该域不匹配的所有域重定向到该example.com文件。

/* eslint-disable @next/next/no-server-import-in-page */
import { NextRequest, NextResponse } from 'next/server';

export function middleware(request: NextRequest) {
  const url = request.nextUrl.clone();

  const isProduction = process.env.NODE_ENV === 'production' // redirect only in production
  const requestedHost = request.headers.get('X-Forwarded-Host');

  if (isProduction && requestedHost && !requestedHost.match(/example.com/)) {
    const host = `example.com`; // set your main domain

    const requestedPort = request.headers.get('X-Forwarded-Port');
    const requestedProto = request.headers.get('X-Forwarded-Proto');

    url.host = host;
    url.protocol = requestedProto || url.protocol;
    url.port = requestedPort || url.port;

    return NextResponse.redirect(url);
  }

  return NextResponse.next();
}

export const config = {
  matcher: '/',
};
Run Code Online (Sandbox Code Playgroud)

现在,所有域example1.com、example2.com和 都example3.com被重定向到example.com包括相同的路径、查询参数和哈希值。