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
相关产品推荐
相关产品推荐

