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

POST请求/register/users报404,GET请求正常的技术求助

注册接口POST请求返回404问题解决

问题场景

使用React.js前端、Node.js+Express后端、PostgreSQL数据库开发注册页面时,出现以下异常:

  • 向/register/users端点发送POST请求返回404 Not Found
  • 发送GET请求到该端点返回200 OK
  • 使用Postman测试POST请求同样得到404响应

前端代码(register.js)

import { useState, useEffect } from "react";
import { Link, useNavigate } from 'react-router-dom';
import bcrypt from 'bcryptjs'

const userRegex = /^[a-zA-Z][a-zA-Z0-9-_]{3,23}$/;
const passRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%]).{8,24}$/;

const Register = () => {

  const navigate = useNavigate();
  const [username, setUser] = useState('');
  const [validUsername, setValidUser] = useState(false);

  const [password, setPass] = useState('');
  const [validPassword, setValidPass] = useState(false);

  useEffect(() => {
    setValidPass(passRegex.test(password));
  }, [password]);

  useEffect(() => {
    setValidUser(userRegex.test(username));
  }, [username]);
 
  const isFormValid = validPassword && validUsername; 
  const handleRegister = async () => {
    if (isFormValid) {
      const hash = bcrypt.hashSync(password, 10)
      const userData = { username: username, password: hash };
      try {
        const response = await fetch('http://localhost:3000/register/users', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify(userData),
        });
        if (response.ok) {
        // Handle success
        console.log('User registered successfully');
        setTimeout(() => {
            navigate('/login');
          },1500);

        } else {
            // Handle error
            console.log('Error occurred during registration');
        }
      }

      
      catch (error) {
        console.error('Error:', error);
      }
    } 
    else {
      alert('Please enter valid fields.');
    }
  };
    return <div className="container">
        <h1>Registration</h1>
        <form>
          <label htmlFor="username">
            <span className={validUsername ? "valid" : "hide"}></span>
            <span className={validUsername || !username ? "hide" : "invalid"}></span>
          </label>
          <input
            type="text"
            placeholder="Username"
            id="username"
            autoComplete="off"
            value={username}
            onChange={(e) => setUser(e.target.value)}
            required
            aria-invalid={!validUsername}
          />

          <label htmlFor="password">
            <span className={validPassword ? "valid" : "hide"}></span>
            <span className={validPassword || !password ? "hide" : "invalid"}></span>
          </label>
          <input
            type="password"
            placeholder="Password"
            id="password"
            autoComplete="off"
            value={password}
            onChange={(e) => setPass(e.target.value)}
            required
            aria-invalid={!validPassword}
          />

          <Link to='/login'>
            <button type="submit" onClick = {handleRegister} disabled={!isFormValid}>Register</button>
            <p>Already have an account?</p>
          </Link>   
        </form>
      </div>  
    
};

export default Register;

后端代码(server.js)

const express = require('express');
const { Sequelize, DataTypes } = require('sequelize');

const app = express();
const port = 3000;

// 创建Sequelize实例并连接PostgreSQL数据库
const sequelize = new Sequelize('postgres://pole_chudes:qwerty@localhost:5432/game');

// 导入已有的User模型
const User = require('./models/users')(sequelize, DataTypes);


sequelize
  .authenticate()
  .then(() => {
    console.log('数据库连接成功。');
  })
  .catch((error) => {
    console.error('无法连接数据库:', error);
  });

(async () => {
  await sequelize.sync();
  console.log('数据库已连接,表已同步');
})();

app.use(express.json());

// 定义注册接口
app.post('/register/users', async (req, res) => {
  const { username, password } = req.body;

  try {
    // 在数据库中创建新用户记录
    const newUser = await User.create({
      username,
      password,
      score:0
    });

    // 返回成功响应
    res.status(200).json({ message: '用户注册成功' });
  } catch (error) {
    // 处理注册过程中的错误
    console.error(error);
    res.status(500).json({ message: '注册过程中发生错误' });
  }
});

// 启动服务器
app.listen(port, () => {
  console.log(`服务器运行在端口 ${port}`);
});

问题排查与解决方案

1. 统一请求协议

前端代码使用http://localhost:3000/register/users,但Postman测试用了https://localhost:3000/register/users,协议不匹配直接导致404。确保所有请求使用相同的协议(http或https)。

2. 阻止表单默认提交行为

前端按钮的type="submit"会触发浏览器默认表单提交,中断异步POST请求,同时按钮被包裹在Link组件中会触发路由跳转,干扰请求执行。修改方案:

  • 将按钮type改为button,并把Link仅用于跳转文本:
    <button type="button" onClick={handleRegister} disabled={!isFormValid}>Register</button>
    <Link to='/login'>
      <p>Already have an account?</p>
    </Link>
    
  • 或在handleRegister中添加阻止默认行为的代码:
    const handleRegister = async (e) => {
      e.preventDefault();
      // 原有逻辑...
    }
    

3. 检查端口冲突与CORS配置

如果前端使用create-react-app启动(默认端口3000),后端也用3000会导致端口冲突,需修改后端端口或配置前端代理。此外,跨域请求需添加CORS支持:

npm install cors

在server.js中引入并使用:

const cors = require('cors');
app.use(cors());

4. 验证后端路由加载

在后端添加GET测试路由,确认端点路径正确:

app.get('/register/users', (req, res) => {
  res.send('GET请求正常');
});

若GET请求正常返回,说明路由路径无误,问题集中在请求本身或数据库模型定义。

5. 检查数据库模型

确认./models/users.js中的User模型包含username、password、score字段,且字段约束不会导致创建失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 09:04:56