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

