Next.js收到无效URL请求报ERR_INVALID_URL崩溃如何处理?
解决方案
ERR_INVALID_URL 错误触发在Next.js处理请求的早期URL解析阶段,早于路由匹配和pages/_error.ts的自定义错误页渲染逻辑,所以常规的错误页方案无法捕获。以下是两种可落地的拦截方案:
方案1:使用Next.js中间件拦截(推荐,Next.js 12+支持)
中间件运行在所有路由处理逻辑之前,可以提前完成URL合法性校验,捕获解析错误直接返回响应,对原有业务代码侵入最小。
// middleware.ts 放在项目根目录或者src目录下 import { NextResponse } from 'next/server' import type { NextRequest } from 'next/server' export function middleware(request: NextRequest) { try { // 主动尝试解析URL,触发可能的ERR_INVALID_URL错误 new URL(request.url) return NextResponse.next() } catch (err) { if ((err as Error).message.includes('ERR_INVALID_URL')) { // 无效URL直接返回400响应,避免错误往下抛导致服务崩溃 return new NextResponse('Invalid URL', { status: 400 }) } // 其他错误继续抛出 throw err } } // 配置中间件匹配所有请求路径 export const config = { matcher: '/:path*', }
方案2:自定义服务外层捕获
如果你使用了自定义Node.js服务启动Next.js,可以在请求进入Next.js处理逻辑前加一层校验:
const { createServer } = require('http') const { parse } = require('url') const next = require('next') const dev = process.env.NODE_ENV !== 'production' const app = next({ dev }) const handle = app.getRequestHandler() app.prepare().then(() => { createServer((req, res) => { try { // 提前解析URL,捕获无效错误 const parsedUrl = parse(req.url, true) handle(req, res, parsedUrl) } catch (err) { if (err.code === 'ERR_INVALID_URL') { res.writeHead(400, { 'Content-Type': 'text/plain' }) res.end('Invalid URL') return } // 其他错误正常处理 res.writeHead(500) res.end('Internal Server Error') } }).listen(3000, (err) => { if (err) throw err console.log('> Ready on http://localhost:3000') }) })
两种方案都可以在错误触发服务崩溃之前完成拦截,不需要修改Next.js内部逻辑,也不需要在业务代码里逐个加try catch。
内容的提问来源于stack exchange,提问作者hopeless-programmer
相关产品推荐
相关产品推荐

