Next 13中如何避免中间件作用于_next/data文件?区域重定向异常
解决Next.js 13多语言重定向导致
_next/data请求失败的问题 问题背景
我们的Next.js应用基于i18n实现多语言支持,URL结构为ourdomain.com/、ourdomain.com/es、ourdomain.com/fr等,部署在Vercel平台。切换语言时通过Cookie保存用户选择,下次访问时利用middleware.ts根据Cookie重定向到对应语言页面。但目前出现异常:/_next/data/下的JSON文件被错误重定向(例如/_next/data/xxxxx/es.json被重定向到/_next/data/xxxxx/esindex.json),导致资源加载失败、应用崩溃。
已尝试但失效的排除方案
- 判断
url.pathname.startsWith('/_next'):Next.js 13中当前构造的URL对象已无pathname属性,无法生效 - 检查Referer请求头:
request.headers.get('referer').indexOf("/_next/data")在Vercel上稳定性差,仍有部分_next/data请求被重定向 - 配置matcher规则:
export const config = { matcher: [ '/((?!api|static|.*\\..*|_next).*)', '/', ], };
根据Vercel文档说明,即使配置路径匹配,Edge Middleware仍会处理所有/_next/data/请求,因此该规则无效。
修正后的Middleware代码
核心改进是采用Next.js 13推荐的路径获取方式,精准排除_next/data路径,并限制重定向触发场景:
import { NextResponse } from "next/server"; const PUBLIC_FILE = /\.(.*)$/; export default function middleware(request) { // 直接从request.nextUrl获取路径,Next.js 13 Edge Middleware标准用法 const pathname = request.nextUrl.pathname; // 精准排除_next/data、其他_next路径、API接口和静态文件 if ( pathname.startsWith('/_next/data') || pathname.startsWith('/_next') || pathname.includes('/api/') || PUBLIC_FILE.test(pathname) ) { return NextResponse.next(); } const { origin } = request.nextUrl; const locale = request.nextUrl.locale; const countryCookie = request.cookies.get('country')?.value; if (countryCookie) { const country = countryCookie.split('|')[0]; // 仅在访问根路径或当前语言根路径时执行重定向,避免子路径误触发 if (country && locale && country !== locale && (pathname === '/' || pathname === `/${locale}/`)) { return NextResponse.redirect(`${origin}/${country}/`); } } return NextResponse.next(); } export const config = { matcher: [ '/((?!api|static|.*\\..*|_next).*)', '/', ], };
关键修正说明
- 路径获取方式:改用
request.nextUrl.pathname获取请求路径,这是Next.js 13中Edge Middleware的标准路径获取方式,替代手动构造的URL对象。 - 精准排除规则:单独判断
pathname.startsWith('/_next/data'),确保这类数据请求完全绕过重定向逻辑。 - 限制重定向场景:仅在用户访问根路径或当前语言根路径时执行重定向,避免子页面关联的
_next/data请求被错误触发。
内容的提问来源于stack exchange,提问作者Laurence Cope
相关产品推荐
相关产品推荐

