Next 12.2 如何链式调用Middleware 合并返回单个NextResponse对象
Next.js 12.2 中间件链式调用标准实现方案
Next.js 12.2 稳定版Middleware没有内置链式调用封装,不需要额外引入第三方工具,也不用大幅改造现有中间件逻辑,核心原则是全程复用同一个NextResponse实例,依次把各中间件的修改合并到这个实例上,避免每个中间件独立创建新响应导致前序修改丢失。
具体实现步骤
- 改造原有两个中间件的入参,新增可选的
NextResponse类型入参,优先复用传入的已有响应实例,没有传入时再初始化默认响应 - 按业务顺序执行中间件,把前一个中间件返回的响应对象作为参数传给下一个中间件
- 所有Cookie设置、重定向规则、响应头修改都作用在同一个响应实例上,最终直接返回这个实例即可,天然同时携带所有配置
可直接复用的代码示例
import { NextRequest, NextResponse } from 'next/server'; // Cookie添加中间件 const addCookieMiddleware = (req: NextRequest, existingRes?: NextResponse) => { // 优先复用传入的已有响应,无传入时初始化默认透传响应 const response = existingRes ?? NextResponse.next(); // 原有Cookie设置逻辑保持不变 response.cookies.set('your_cookie_key', 'your_cookie_value', { httpOnly: true, sameSite: 'strict', path: '/', // 其余Cookie配置按业务需求填写 }); return response; }; // 重定向匹配中间件 const findRedirectsMiddleware = (req: NextRequest, existingRes?: NextResponse) => { const response = existingRes ?? NextResponse.next(); // 原有重定向匹配逻辑保持不变 const redirectTarget = '/target-page'; // 替换为实际匹配得到的重定向路径 if (redirectTarget) { // 直接在已有响应实例上设置重定向状态和头,保留之前设置的所有Cookie response.headers.set('Location', new URL(redirectTarget, req.url).toString()); response.status = 307; // 按需选择重定向状态码:301/302/307/308 } return response; }; // 中间件入口 export const middleware = (req: NextRequest): NextResponse => { // 按顺序执行,透传前序中间件处理后的响应对象 const resWithCookie = addCookieMiddleware(req); const finalResponse = findRedirectsMiddleware(req, resWithCookie); // 返回的单个响应会同时携带已设置Cookie和重定向配置 return finalResponse; };
注意事项
- 禁止在各业务中间件里独立调用
NextResponse.next()/NextResponse.redirect()生成新对象直接返回,否则前序中间件写入的Cookie、响应头会全部丢失 - 如果后续需要新增更多中间件(比如权限校验、请求头添加等),直接按相同规则顺序传参即可,链式扩展非常方便
- 如果重定向逻辑必须生成全新的响应实例,记得遍历前序响应的
cookies.getAll()结果,把所有Cookie复制到新响应上,避免配置丢失
内容的提问来源于stack exchange,提问作者Michael Nguyen
相关产品推荐
相关产品推荐

