Next.js middleware中map/forEach下NextResponse.redirect()失效for循环正常
Next.js Middleware 中 map 写法重定向不生效原因排查
核心根因
Array.map() 是数组值映射方法,回调函数内的返回值只会成为新数组的元素,不会作为外层 middleware 主函数的返回值传递给 Next.js 运行时。
- 你能在控制台看到
match日志,是因为map遍历到匹配规则时确实执行了回调内的打印逻辑,但回调里返回的NextResponse.redirect()对象被封装在map生成的新数组中,从来没有被外层middleware函数返回。Next.js拿不到重定向响应对象,自然不会执行跳转逻辑,最终会按原请求路径继续处理。 for...of循环内的return是直接作用于外层middleware函数的,命中规则后会直接把重定向响应对象返回给Next.js执行器,所以能正常触发跳转。
两种写法的行为差异
失效的 filter+map 写法逻辑
// 无法触发重定向 rules.filter(rule => rule.type === 'redirect' && new RegExp(rule.rule).exec(pathname.slice(1))) .map(rule => { console.log('match'); const url = req.nextUrl.clone() url.pathname = rule.destination // 该返回值仅传入map生成的新数组,不会被middleware主函数返回 return NextResponse.redirect(url) }) // 函数执行到此处无显式返回值,默认返回undefined,Next.js识别不到重定向指令
正常生效的 for...of 写法逻辑
// 可正常触发重定向 for (let rule of rules) { const regex: RegExp = new RegExp(rule.rule) if(regex.exec(pathname.slice(1)) && rule.type === 'redirect') { console.log('match'); const url = req.nextUrl.clone() url.pathname = rule.destination // 该返回值直接作为middleware主函数的返回值传给Next.js return NextResponse.redirect(url) } }
链式写法的正确实现
如果想保留数组链式调用的写法,不要用map做逻辑分支返回,应该用Array.find()拿到第一个匹配的规则后,显式返回重定向结果:
// 链式调用的正确写法 const matchedRedirectRule = rules.find(rule => { return rule.type === 'redirect' && new RegExp(rule.rule).test(pathname.slice(1)) }) if (matchedRedirectRule) { console.log('match'); const url = req.nextUrl.clone() url.pathname = matchedRedirectRule.destination return NextResponse.redirect(url) }
注:做正则存在性判断优先用
test()而非exec(),如果正则带全局g标识,exec()会缓存上次匹配的lastIndex位置,容易出现偶发匹配失效问题。
内容的提问来源于stack exchange,提问作者Sebastian Vecchio
相关产品推荐
相关产品推荐

