使用SolidJs+NestJS+Prisma开发注册页提交表单遇404错误
问题:用户注册接口返回404 Not Found
我使用SolidJS、NestJS搭配Prisma开发用户注册页面,提交表单时出现错误:POST http://127.0.0.1:3000/user/register 404 (Not Found),Axios也返回相同错误。PostgreSQL数据库的Schema、迁移配置均正常。
相关代码
schema.prisma
generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id Int @id @default(autoincrement()) email String @unique username String? password String? }
Prisma.service.ts
import { PrismaClient, User } from '@prisma/client'; const prisma = new PrismaClient(); export class PrismaService { private prisma: PrismaClient; constructor() { this.prisma = prisma; } async createUser(data: Omit<User, 'id'>): Promise<User> { return this.prisma.user.create({ data, }); } }
user.controller.ts
import { Body, Controller, Post } from '@nestjs/common'; import { PrismaService } from '../prisma.service'; @Controller('user') export class UserController { constructor(private readonly prismaService: PrismaService) {} @Post('/register') async register(@Body() data: { username:string, email: string, password: string }) { const { username, email, password } = data; const newUser = await this.prismaService.createUser({ username, email, password }); return { message: 'User registered successfully', newUser }; } }
RegisterComponent.jsx
import { createSignal } from 'solid-js'; import axios from "axios"; const [username, setUsername] = createSignal(''); const [email, setEmail] = createSignal(''); const [password, setPassword] = createSignal(''); const handleSubmit = async (e) => { e.preventDefault(); try { const response = await axios.post('/api/user/register', { username, email, password }); console.log(response.data); } catch (error) { console.error(error); } }; function RegisterComponent(){ return( <section class="bg-center bg-no-repeat bg-[url('https://media.thegospelcoalition.org/wp-content/uploads/2023/04/04185025/build-theological-library-1920x1080.jpg')] bg-gray-700 bg-blend-multiply"> <div class="px-4 mx-auto max-w-screen-xl text-center py-24 lg:py-56"> <div class="flex flex-col space-y-4 sm:flex-row sm:justify-center sm:space-y-0 sm:space-x-4"> <div class="flex min-h-full flex-col justify-center px-6 py-12 lg:px-8"> <div class="sm:mx-auto sm:w-full sm:max-w-sm"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 22 22" strokeWidth={1.5} stroke="currentColor" class="mx-auto h-10 w-auto w-6 sm:h-9 h-6 dark:text-white"> <path strokeLinecap="round" strokeLinejoin="round" d="M12 6.042A8.967 8.967 0 006 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 016 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 016-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0018 18a8.967 8.967 0 00-6 2.292m0-14.25v14.25" /> </svg> <h2 class="mt-10 text-center text-2xl font-bold leading-9 tracking-tight text-white">Crie sua Conta</h2> </div> <div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm"> <form class="space-y-6" action="#" onSubmit={handleSubmit} method="POST"> <div> <label for="text" class="block text-sm font-medium leading-6 text-white">Nome de usuário</label> <div class="mt-2"> <input value={username()} onInput={(e) => setUsername(e.target.value)} id="username" name="username" type="text" autocomplete="email" required class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"></input> </div> </div> <div> <label for="email" class="block text-sm font-medium leading-6 text-white">E-mail</label> <div class="mt-2"> <input value={email()} onInput={(e) => setEmail(e.target.value)} id="email" name="email" type="email" autocomplete="email" required class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"></input> </div> </div> <div> <label for="password" class="block text-center text-sm font-medium leading-6 text-white">Senha</label> <div class="mt-2"> <input value={password()} onInput={(e) => setPassword(e.target.value)} id="password" name="password" type="password" autocomplete="current-password" required class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"> </input> </div> </div> <div> <button type="submit" class="flex w-full justify-center rounded-md bg-white dark:bg-blue-900 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Entrar</button> </div> </form> <p class="mt-10 text-center text-sm text-gray-500"> Nao possui conta? <a href="#" class="font-semibold m-4 leading-6 text-indigo-600 hover:text-indigo-500">Crie sua Conta</a> </p> </div> </div> </div> </div> </section> ) }export default RegisterComponent;
排查与解决方法
1. 请求路径不匹配
前端Axios请求的是/api/user/register,但NestJS接口路由为/user/register,可通过以下方式修正:
- 修改前端请求路径:将
axios.post('/api/user/register', ...)改为axios.post('/user/register', ...),需确保NestJS与SolidJS运行在同一端口,或已配置代理。 - 给NestJS添加全局前缀:在
main.ts中添加全局前缀api:
同时在SolidJS的import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.setGlobalPrefix('api'); await app.listen(3001); } bootstrap();vite.config.ts中配置代理:import { defineConfig } from 'vite'; import solidPlugin from 'vite-plugin-solid'; export default defineConfig({ plugins: [solidPlugin()], server: { proxy: { '/api': { target: 'http://localhost:3001', changeOrigin: true, }, }, }, });
2. 未在NestJS模块中注册UserController
检查AppModule(或对应UserModule),确保UserController已添加到controllers数组:
import { Module } from '@nestjs/common'; import { UserController } from './user/user.controller'; import { PrismaService } from './prisma.service'; @Module({ controllers: [UserController], providers: [PrismaService], }) export class AppModule {}
3. 服务端口冲突
SolidJS默认运行在3000端口,若NestJS也使用3000端口会导致冲突,需修改其中一个服务的端口(如让NestJS运行在3001端口),再通过代理转发请求。
4. 前端请求数据格式修正
前端传递的username、email、password是Signal对象,需传递其原始值:
const response = await axios.post('/api/user/register', { username: username(), email: email(), password: password() });
内容的提问来源于stack exchange,提问作者Hjaeter
相关产品推荐
相关产品推荐

