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

Next.js 13 + MySQL 添加记录时报TypeError: resolver is not a function

问题描述

在使用Next.js 13和MySQL服务器时,尝试向数据库添加记录时遇到TypeError: resolver is not a function错误,怀疑异步函数使用有误,但移除部分异步函数仅打印数据后仍未解决。相关代码及错误信息如下:

API文件

import executeQuery from "@/pages/api/db";

export async function handler(req, res){
  if(req.method === "POST"){
    const data = req.body;
    // console.log(data);
    const { naam, email, telefoon, datum, aantal, aankomst, opm  } = data;

    // add reservering in reserv table
    const result = await executeQuery(
      `INSERT INTO reservering (naam, email, telefoon, datum, aantal, aankomst, opm) VALUES (${naam},${email},${telefoon},${datum},${aantal},${aankomst},${opm})`,
      );
    // check if email is in email_voorkeur table

    // if in not in add in table

    //same with telefoon

    console.log(result);
    res.status(201);
  }
}

页面文件(带表单)

import logo from "../../public/logo.png";
import Form from "@/components/ui/form";

import { Fragment } from "react";

export default function HomePage() {
  async function addReservHandler(data) {
    console.log(data);
    const response = await fetch('/api/newReserv',{
      method: 'POST',
      body: JSON.stringify(data),
      headers: {
        'Content-Type': 'application/json'
      }
    });
    // console.log(response.json());
  }

  return (
    <Fragment>
      <div>
        <h1>Reserveringen</h1>
        <img src={logo} alt="logo DevikingODK" />
      </div>
      <div>
        <Form onAddReserv={addReservHandler} />
      </div>
    </Fragment>
  );
}

表单文件

import { Fragment, useRef } from "react";

export default function Form(props) {
  const naamInputRef = useRef();
  const emailInputRef = useRef();
  const telefoonInputRef = useRef();
  const datumInputRef = useRef();
  const aantalInputRef = useRef();
  const aankomstInputRef = useRef();
  const opmInputRef = useRef();

  function submitHandler(event) {
    event.preventDefault();

    const enteredNaam = naamInputRef.current.value;
    const enteredEmail = emailInputRef.current.value;
    const enteredTelefoon = telefoonInputRef.current.value;
    const enteredDatum = datumInputRef.current.value;
    const enteredAantal = aantalInputRef.current.value;
    const enteredAankomst = aankomstInputRef.current.value;
    const enteredOpm = opmInputRef.current.value;

    const reservering = {
      naam: enteredNaam,
      email: enteredEmail,
      telefoon: enteredTelefoon,
      datum: enteredDatum,
      aantal: enteredAantal,
      aankomst: enteredAankomst,
      opm: enteredOpm,
    };

    props.onAddReserv(reservering);
  }

  return (
    <Fragment>
      <form method="POST" onSubmit={submitHandler}>
        <label>
          Naam:
          <input type="text" name="naam" ref={naamInputRef}/>
        </label>
        <label>
          E-mail:
          <input type="text" name="email" ref={emailInputRef}/>
        </label>
        <label>
          Telefoon:
          <input type="tel" name="telefoon" ref={telefoonInputRef}/>
        </label>
        <label>
          Datum:
          <input type="date" name="datum" ref={datumInputRef}/>
        </label>
        <label>
          Aantal:
          <input type="number" name="aantal" ref={aantalInputRef}/>
        </label>
        <label>
          Aankomstuur:
          <input type="time" name="tijd" ref={aankomstInputRef}/>
        </label>
        <label>
          Opmerking:
          <input type="text" name="opmerking" ref={opmInputRef}/>
        </label>
        <button>Reserveren</button>
      </form>
    </Fragment>
  );
}

完整错误信息

error - TypeError: resolver is not a function
    at Object.apiResolver (C:\Users\cuyve\Desktop\VIKING\reserveringViking\node_modules\next\dist\server\api-utils\node.js:372:15)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async DevServer.runApi (C:\Users\cuyve\Desktop\VIKING\reserveringViking\node_modules\next\dist\server\next-server.js:488:9)
    at async Object.fn (C:\Users\cuyve\Desktop\VIKING\reserveringViking\node_modules\next\dist\server\next-server.js:751:37)
    at async Router.execute (C:\Users\cuyve\Desktop\VIKING\reserveringViking\node_modules\next\dist\server\router.js:253:36)
    at async DevServer.run (C:\Users\cuyve\Desktop\VIKING\reserveringViking\node_modules\next\dist\server\base-server.js:384:29)
    at async DevServer.run (C:\Users\cuyve\Desktop\VIKING\reserveringViking\node_modules\next\dist\server\dev\next-dev-server.js:743:20)
    at async DevServer.handleRequest (C:\Users\cuyve\Desktop\VIKING\reserveringViking\node_modules\next\dist\server\base-server.js:322:20) {
  page: '/api/newReserv'
}
解决方法

1. 修正API路由的导出方式

Next.js 13的Pages Router中,API路由要求默认导出处理函数,而非命名导出handler。你的API文件里用了export async function handler,这会导致Next.js找不到正确的解析器,从而抛出resolver is not a function错误。

修改API文件的导出部分:

// 替换原来的export async function handler
export default async function handler(req, res){
  if(req.method === "POST"){
    const data = req.body;
    const { naam, email, telefoon, datum, aantal, aankomst, opm  } = data;

    // add reservering in reserv table
    const result = await executeQuery(
      `INSERT INTO reservering (naam, email, telefoon, datum, aantal, aankomst, opm) VALUES (${naam},${email},${telefoon},${datum},${aantal},${aankomst},${opm})`,
      );

    console.log(result);
    res.status(201).json({ message: "Reservering added" }); // 补充返回响应内容
  } else {
    res.status(405).json({ message: "Method not allowed" }); // 处理非POST请求
  }
}

2. 修复SQL注入风险

当前的SQL语句直接拼接用户输入,存在严重的SQL注入漏洞。必须使用参数化查询:

// 修改executeQuery的调用方式(假设executeQuery支持参数数组)
const result = await executeQuery(
  `INSERT INTO reservering (naam, email, telefoon, datum, aantal, aankomst, opm) VALUES (?, ?, ?, ?, ?, ?, ?)`,
  [naam, email, telefoon, datum, aantal, aankomst, opm]
);

3. 完善API响应处理

原代码中仅设置了res.status(201)但未返回任何响应内容,需要调用res.json()或res.end()来完成响应,否则客户端会一直处于等待状态。

4. 客户端处理响应

页面文件的addReservHandler中可以补充处理响应的逻辑:

async function addReservHandler(data) {
  console.log(data);
  try {
    const response = await fetch('/api/newReserv',{
      method: 'POST',
      body: JSON.stringify(data),
      headers: {
        'Content-Type': 'application/json'
      }
    });
    if (!response.ok) {
      throw new Error('Failed to add reservation');
    }
    const result = await response.json();
    console.log(result.message);
  } catch (error) {
    console.error(error);
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 22:44:55