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

Next.js中间件如何获取不含端口号的正确pathname值?

解决Next.js与Express配合时重定向带端口号的问题

问题原因

当Express与Next.js配合部署时,Next.js可能从请求头或内部解析逻辑中拿到带端口的主机名(比如默认开发端口3000),导致重定向时错误地将端口号附加到目标URL中。

解决方案

1. 在Next.js中间件中手动剥离端口并构造正确URL

直接在中间件里使用URL对象解析请求地址,提取不带端口的主机名和小写路径,构造正确的重定向URL:

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  const requestUrl = new URL(request.url)
  const lowerPath = requestUrl.pathname.toLowerCase()

  if (requestUrl.pathname !== lowerPath) {
    // 用原协议+不带端口的主机名+小写路径构造新URL
    const redirectUrl = new URL(lowerPath, `${requestUrl.protocol}//${requestUrl.hostname}`)
    // 保留原查询参数
    redirectUrl.search = requestUrl.search
    
    return NextResponse.redirect(redirectUrl, { status: 301 })
  }

  return NextResponse.next()
}

2. 配置Express信任代理并传递正确Host头

如果是生产环境通过反向代理(如Nginx)部署,需要让Express信任代理,确保Next.js能获取到客户端真实的Host头(不带端口):

在Express服务代码中添加:

const express = require('express')
const next = require('next')

const app = express()
// 信任所有代理,让Express能拿到真实的客户端请求头
app.set('trust proxy', true)

const nextApp = next({ dev: process.env.NODE_ENV !== 'production' })
const handle = nextApp.getRequestHandler()

nextApp.prepare().then(() => {
  app.all('*', (req, res) => handle(req, res))
  app.listen(3000, () => console.log('Server running on port 3000'))
})

如果使用Nginx反向代理,需配置传递正确的Host头:

location / {
  proxy_pass http://localhost:3000;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
}

关键说明

  • requestUrl.hostname会自动剥离端口号,只保留域名部分,用它来构造重定向URL就能避免端口号出现。
  • 生产环境务必配置反向代理传递正确的Host头,同时Express开启trust proxy,这样Next.js能始终拿到客户端请求的真实域名(不带端口)。

内容的提问来源于stack exchange,提问作者Darshan Sachaniya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 15:15:13