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

使用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:
    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();
    
    同时在SolidJS的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 09:04:55