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

如何在Next.js中间件中使用异步自定义Hook?

问题分析与解决方案

错误原因

  1. React Hook规则违反:自定义Hook(以use开头)只能在React函数组件或其他自定义Hook内部调用,不能直接在Next.js中间件这种普通服务器端函数中使用。
  2. 环境不兼容:中间件运行在边缘/服务器端环境,不存在浏览器的document对象,你的代码中引入的依赖(如emotion)尝试访问document导致报错。
  3. 相对路径无效:中间件中使用相对路径/redirect/list发起fetch请求会失败,因为服务器端没有浏览器的页面上下文,必须使用完整URL。

修正方案

将原自定义Hook重构为普通异步工具函数,脱离React Hook体系,适配中间件的运行环境:

1. 重构重定向检查逻辑为普通函数

创建redirectUtils.js文件:

export const getRedirectChecker = async () => {
    // 使用完整URL发起请求,可通过环境变量或request上下文获取域名
    const baseUrl = process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'
    const response = await fetch(`${baseUrl}/redirect/list`)
    const redirects = await response.json()

    const checkRedirection = (url) => {
        let isRedirected = false
        let newUrl = url.href

        // 补全你的重定向匹配逻辑,示例如下:
        const matchedRule = redirects.find(rule => url.pathname === rule.from)
        if (matchedRule) {
            isRedirected = true
            newUrl = `${url.origin}${matchedRule.to}`
        }

        return { isRedirected, newUrl }
    }

    return checkRedirection
}

2. 修改中间件代码

更新middleware.js:

import { NextResponse } from 'next/server'
import { getRedirectChecker } from './redirectUtils'

export async function middleware(request) {
    // 跳过Next.js内部资源请求
    if (request.nextUrl.pathname.startsWith('/_next')) {
        return NextResponse.next()
    }

    const checkRedirection = await getRedirectChecker()
    const { isRedirected, newUrl } = checkRedirection(request.nextUrl)
    
    if (isRedirected) {
        // 返回标准的重定向响应
        return NextResponse.redirect(newUrl)
    }

    // 无重定向时继续请求流程
    return NextResponse.next()
}

关键说明

  • 去掉use前缀,将逻辑转为纯服务器端可执行的工具函数,避免Hook规则限制。
  • 确保fetch请求使用完整URL,可通过环境变量NEXT_PUBLIC_APP_URL配置生产环境域名,本地开发默认使用http://localhost:3000。
  • 中间件必须返回NextResponse对象,不能直接返回字符串URL,否则会导致响应格式错误。

内容的提问来源于stack exchange,提问作者Ali EXE

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 02:05:57