【问题标题】:Cannot read req.body in Next.js 13 middeware无法在 Nextjs 13 中间件中读取 req.body
【发布时间】:2023-02-03 07:45:05
【问题描述】:

在下面的代码中,我想使用来自 zod 的模式验证请求主体,目前,它将失败并捕获。这是因为 req.body 返回的是 ReadableStream<Uint8Array> 而不是它期望解析的对象。

export default async function middleware(req: NextRequest, res: NextResponse) {
  const { pathname } = req.nextUrl;
  if (pathname.startsWith('/api/user/create')) {
    try {
      createUserSchema.parse({
        body: req.body,
        params: req.nextUrl.searchParams,
      });
      return NextResponse.next();
    } catch (error: any) {
      console.log(req.body);
      return NextResponse.json(
        { success: false, message: error },
        { status: 422, headers: { 'content-type': 'application/json' } }
      );
    }
  }

  return NextResponse.next();
}

下面是 console.log(req.body); 的输出

<ref *1> ReadableStream {
  _state: 'readable',
  _reader: undefined,
  _storedError: undefined,
  _disturbed: false,
  _readableStreamController: ReadableStreamDefaultController {
  _controlledReadableStream: [Circular *1],
  _queue: S {
  _cursor: 0,
  _size: 0,
  _front: { _elements: [], _next: undefined },
  _back: { _elements: [], _next: undefined }
},
  _queueTotalSize: 0,
  _started: false,
  _closeRequested: false,
  _pullAgain: false,
  _pulling: false,
  _strategySizeAlgorithm: [Function],
  _strategyHWM: 1,
  _pullAlgorithm: [Function],
  _cancelAlgorithm: [Function]
}
}

我做了一些研究,发现我需要在这个 ReadableStream 上运行某种转换方法。问题是其中大部分包含无法在 Edge 上运行的 Buffer 模块,因此无法在 middleware.ts 中工作。是否有我可以使用的 polyfill?

"next": "^13.0.7" Node v16.17.0

【问题讨论】:

    标签: javascript next.js zod nextjs13


    【解决方案1】:

    Next.js 中间件与 Express 中间件的工作方式不同,因为它只在导航上运行,并不充当 API 端点的包罗万象。

    根据the documentation,您只能使用此功能访问 cookie、访问/修改请求标头以及执行重定向和重写。

    【讨论】:

    • 但是有没有办法实现我正在尝试做的事情(在到达端点之前验证中间件中的发布请求正文)?我可以将自定义 express 中间件添加到 api 路由,还是仅限于 Next.js middleware.ts?
    • 我已根据@emeraldsanto 的响应和声明如下的 Next.js 中间件文档将此逻辑移动到单独的 api 端点:To respect the differences in client-side and server-side navigation, and to help ensure that developers do not build insecure Middleware, we are removing the ability to send response bodies in Middleware. This ensures that Middleware is only used to rewrite, redirect, or modify the incoming request (e.g. setting cookies).
    【解决方案2】:

    您可以使用

    const body = await req.json()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-11
      • 2022-11-20
      • 1970-01-01
      • 2022-01-12
      • 2014-07-16
      • 2023-02-26
      • 2021-05-03
      相关资源
      最近更新 更多