You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 14+TRPC+MongoDB注册时出现Response body锁定错误

Next.js 14 + TRPC + PayloadCMS 注册时500错误排查求助

在Windows 10环境下搭建了基于Next.js 14、TRPC、PayloadCMS和本地MongoDB的应用,用户注册时浏览器返回500错误,控制台提示TypeError: Response body object should not be disturbed or locked。排查发现请求未进入TRPC路由的mutation处理逻辑,已经尝试移除URL中的环境变量、改用httpLink替代httpBatchLink,但问题仍未解决。相关代码如下:

TRPC auth router

import { TRPCError } from "@trpc/server"
import { getPayloadClient } from "../get-payload"
import { AuthCredentialsValidator } from "../lib/validators/account-credentials-validator"
import { publicProcedure, router } from "./trpc"
import { NextResponse } from "next/server"

export const authRouter = router({
  createPayloadUser: publicProcedure
    .input(AuthCredentialsValidator)
    .mutation(async ({ input }) => {
      const { email, password } = input
      const payload = await getPayloadClient()

      // 检查用户是否已存在
      const { docs: users } = await payload.find({
        collection: "users",
        where: {
          email: {
            equals: email,
          },
        },
      })

      if (users.length !== 0) throw new TRPCError({ code: "CONFLICT" })

      await payload.create({
        collection: "users",
        data: {
          email,
          password,
          role: "user",
        },
      })

      return NextResponse.json({ success: true, sentToEmail: email })
    }),
})

Providers.tsx

"use client"

import { trpc } from "@/trpc/client"
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
import { httpBatchLink } from "@trpc/client"
import { PropsWithChildren, useState } from "react"

const Providers = ({ children }: PropsWithChildren) => {
  const [queryClient] = useState(() => new QueryClient())
  const [trpcClient] = useState(() =>
    trpc.createClient({
      links: [
        httpBatchLink({
          url: `${process.env.NEXT_PUBLIC_SERVER_URL}/api/trpc`,
          fetch(url, options) {
            return fetch(url, { // 浏览器控制台提示此处报错
              ...options,
              credentials: "include",
            })
          },
        }),
      ],
    })
  )

  return (
    <trpc.Provider
      client={trpcClient}
      queryClient={queryClient}>
      <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
    </trpc.Provider>
  )
}

export default Providers

注册页面(Sign-up page)

"use client"

import { Icons } from "@/components/Icons"
import { Button, buttonVariants } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { cn } from "@/lib/utils"
import {
  AuthCredentialsValidator,
  TAuthCredentialsValidator,
} from "@/lib/validators/account-credentials-validator"
import { trpc } from "@/trpc/client"
import { zodResolver } from "@hookform/resolvers/zod"
import { ArrowRight } from "lucide-react"
import Link from "next/link"
import { useForm } from "react-hook-form"

const Page = () => {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<TAuthCredentialsValidator>({
    resolver: zodResolver(AuthCredentialsValidator),
  })

  const { mutate, isLoading } = trpc.auth.createPayloadUser.useMutation({
    onError: (err) => {},
    onSuccess: ({}) => {},
  })

  const onSubmit = ({ email, password }: TAuthCredentialsValidator) => {
    mutate({ email, password })
  }

  return (...此处省略JSX代码)

}

export default Page

package.json

{
  "name": "digitalhippo",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "full": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts nodemon",
    "generate:types": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts payload generate:types",
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@hookform/resolvers": "^3.3.4",
    "@payloadcms/bundler-webpack": "^1.0.6",
    "@payloadcms/db-mongodb": "^1.4.0",
    "@payloadcms/richtext-slate": "^1.4.0",
    "@radix-ui/react-dialog": "^1.0.5",
    "@radix-ui/react-label": "^2.0.2",
    "@radix-ui/react-separator": "^1.0.3",
    "@radix-ui/react-slot": "^1.0.2",
    "@tanstack/react-query": "4.36.1",
    "@trpc/client": "^10.45.0",
    "@trpc/next": "^10.45.0",
    "@trpc/react-query": "^10.45.0",
    "@trpc/server": "^10.45.0",
    "class-variance-authority": "^0.7.0",
    "clsx": "^2.1.0",
    "cross-env": "^7.0.3",
    "dotenv": "^16.4.1",
    "lucide-react": "^0.314.0",
    "next": "14.1.0",
    "payload": "^2.9.0",
    "react": "^18",
    "react-dom": "^18",
    "react-hook-form": "^7.49.3",
    "sonner": "^1.3.1",
    "tailwind-merge": "^2.2.1",
    "tailwindcss-animate": "^1.0.7",
    "ts-node": "^10.9.2",
    "zod": "^3.22.4"
  },
  "devDependencies": {
    "@types/express": "^4.17.21",
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "autoprefixer": "^10.0.1",
    "eslint": "^8",
    "eslint-config-next": "14.1.0",
    "nodemon": "^3.0.3",
    "postcss": "^8",
    "tailwindcss": "^3.3.0",
    "typescript": "^5"
  }
}

服务器配置

import * as trpcExpress from "@trpc/server/adapters/express"
import express from "express"
import { getPayloadClient } from "./get-payload"
import { nextApp, nextHandler } from "./next-utils"
import { appRouter } from "./trpc"

const app = express()
const PORT = Number(process.env.PORT) || 3000

const createContext = ({
  req,
  res,
}: trpcExpress.CreateExpressContextOptions) => ({
  req,
  res,
})

const start = async () => {
  const payload = await getPayloadClient({
    initOptions: {
      express: app,
      onInit: async (cms) => {
        cms.logger.info(`Admin URL ${cms.getAdminURL()}`)
      },
    },
  })

  app.use((req, res) => nextHandler(req, res))

  app.use(
    "/api/trpc",
    trpcExpress.createExpressMiddleware({
      router: appRouter,
      createContext,
    })
  )

  nextApp.prepare().then(() => {
    payload.logger.info("Next.js started")

    app.listen(PORT, async () => {
      payload.logger.info(
        `Next.js App URL: ${process.env.NEXT_PUBLIC_SERVER_URL}`
      )
    })
  })
}

start()

内容的提问来源于stack exchange,提问作者Ioann Kurchin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 06:27:32