如何实现发起异步DB请求的SvelteKit POST接口并解决返回404问题
我访问SvelteKit POST接口时,如果提交的参数未通过校验,接口可以正常返回正确的状态码和响应体。但执行DB插入操作时,尽管用户数据成功写入数据库,接口却返回404错误。我推测原因是DB调用为异步操作,SvelteKit没有等待结果返回,但不知道如何修改代码才能让接口等待异步执行完成后返回正确的JSON响应。
感谢大家的帮助!
import type { EndpointOutput } from '@sveltejs/kit'; import bcrypt from 'bcrypt'; import { randomUUID } from 'crypto'; import db from '$lib/config/db.js'; import { roles } from '$lib/config/roles.js'; import validation from '$lib/_helpers/validation'; export async function post({ body }: { body: { firstName: string; lastName: string; emailAddress: string; password: string }; }): Promise<EndpointOutput> { // 去除字段首尾空白字符 console.log(body); const firstName = body?.firstName.trim(); const lastName = body?.lastName.trim(); const email = body?.emailAddress.trim(); const password = body?.password.trim(); const userRole = roles.web + roles.anonymous; const bcryptPassword = await bcrypt.hash(password, 10); const emailToken = randomUUID(); // 二次校验字段,防止用户直接调用接口提交数据 if (validation.validateEmail(email) == false) { //console.log(email); return { status: 422, body: { message: '请输入合法的邮箱地址' } }; } if (validation.validatePassword(password) == false) { return { status: 422, body: { message: '密码长度至少为6位' } }; } if (validation.validateNotEmpty(firstName) == false) { return { status: 422, body: { message: '请填写名字' } }; } if (validation.validateDisplayName(lastName) == false) { return { status: 422, body: { message: '请填写姓氏' } }; } // 插入用户数据 await db.query( 'INSERT INTO users (first_name, last_name, email, user_password, user_role, email_verification_token) VALUES ($1, $2, $3, $4, $5, $6)', [firstName, lastName, email, bcryptPassword, userRole, emailToken], (error, results) => { // console.log(error, results); if (error) { return { status: 417, body: { message: error.toString() } }; } //console.log(results); return { status: 201, body: { message: '用户创建成功' } }; } ); }
更新修复方案
我最终改用pg-promise包而非pg包来连接数据库,以下是更新后的代码,可供遇到同类问题的开发者参考:
import type { EndpointOutput } from '@sveltejs/kit'; import bcrypt from 'bcrypt'; import { randomUUID } from 'crypto'; import { roles } from '$lib/config/roles.js'; import validation from '$lib/_helpers/validation'; import { db } from '$lib/config/db.js'; export async function post({ body }: { body: { firstName: string; lastName: string; emailAddress: string; password: string }; }): Promise<EndpointOutput> { // 去除字段首尾空白字符 console.log(body); const firstName = body?.firstName.trim(); const lastName = body?.lastName.trim(); const email = body?.emailAddress.trim(); const password = body?.password.trim(); const userRole = roles.web + roles.anonymous; const bcryptPassword = await bcrypt.hash(password, 10); const emailToken = randomUUID(); // 二次校验字段,防止用户直接调用接口提交数据 if (validation.validateEmail(email) == false) { //console.log(email); return { status: 422, body: { message: '请输入合法的邮箱地址' } }; } if (validation.validatePassword(password) == false) { return { status: 422, body: { message: '密码长度至少为6位' } }; } if (validation.validateNotEmpty(firstName) == false) { return { status: 422, body: { message: '请填写名字' } }; } if (validation.validateDisplayName(lastName) == false) { return { status: 422, body: { message: '请填写姓氏' } }; } // 检查用户是否已存在 const userAlreadyExists = await db.oneOrNone('SELECT email from users WHERE email=$1 LIMIT 1', [ email ]); console.log(' result: ' + userAlreadyExists); if (userAlreadyExists) { return { status: 409, body: { message: '该邮箱对应的用户已存在' } }; } try { // 向DB插入新用户数据 await db.none( 'INSERT INTO users (first_name, last_name, email, user_password, user_role, email_verification_token) VALUES ($1, $2, $3, $4, $5, $6)', [firstName, lastName, email, bcryptPassword, userRole, emailToken] ); return { status: 201, body: { message: '用户创建成功' } }; } catch (error) { return { status: 417, body: { message: error.toString() } }; } }
内容的提问来源于stack exchange,提问作者Jeff McMorris
相关产品推荐
相关产品推荐

