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

如何用Node.js API与React.js提交表单数据?报错求助

React表单提交到Express服务器出现404和JSON解析错误的排查与修复

问题场景

我搭建了一个包含Express后端和React前端的项目,项目结构如下:

  • Server.js
  • ClientFolder(包含public目录和src目录,src下有Register.js组件)
  • routes目录(包含users.js)

已经在package.json中配置了代理服务器,但在React的Register组件提交表单时,浏览器控制台出现两个错误:

Failed to load resource: the server responded with a status of 404 (Not Found)
index.js:1375 Error: SyntaxError: Unexpected token < in JSON at position 0

下面是相关代码,帮忙排查并解决表单提交失败的问题。


错误原因与修复步骤

1. 路由文件命名不匹配(导致404的核心原因)

你的Server.js中引入路由时使用的是./routes/users,但提供的路由文件是Routes/user.js(注意文件名是user.js而非users.js,还有目录名大小写差异)。Express会严格按照路径查找文件,找不到对应路由时会返回404错误,而服务器通常会返回HTML格式的错误页面,这就导致前端尝试解析JSON时遇到<(HTML标签的开头),触发Unexpected token <错误。

修复:
将路由文件重命名为users.js(保持和Server.js中的引入路径一致),或者修改Server.js中的引入路径为./routes/user(推荐前者,保持文件名复数形式的一致性)。

2. 路由处理函数中的变量名不统一

在routes/users.js中,你给路由处理函数的参数是request和response,但函数内部却使用了req和res,这会导致req is not defined的错误,进而服务器返回500错误,同样会导致前端解析JSON失败。

修复:
统一参数名,将函数参数改为req和res,修改后的路由代码:

const express = require('express');
const router = express.Router();
const jwt = require('jsonwebtoken');
// 引入Server.js中的数据库连接(需要先在Server.js导出connection)
const connection = require('../Server').connection; 

router.use(express.urlencoded({ extended: true }));
router.use(express.json());

// 统一参数名为req和res
router.post('/', function(req, res) {
  var user = {
    username: req.body.username,
    email: req.body.email,
    password: req.body.password,
    userType: req.body.userType,
    team: req.body.team
  };
  connection.query('INSERT INTO players SET ?', user, function(error, results, fields) {
    if (error) {
      console.log('error occurred', error);
      res.send({ code: 400, failed: 'error occurred' });
    } else {
      console.log('The solution is: ', results);
      res.send({ code: 200, success: 'user registered successfully' });
    }
  });
});

module.exports = router;

同时在Server.js中导出数据库连接:

// 在Server.js的connection定义后添加
module.exports.connection = connection;

3. 数据库连接未在路由中可用

路由文件routes/users.js中直接使用了connection变量,但这个变量是在Server.js中定义的,路由文件无法直接访问,会导致ReferenceError: connection is not defined错误。

修复:
如上面的代码所示,在Server.js中导出connection并在路由文件中引入;更规范的做法是将数据库连接逻辑抽离到单独的文件(比如db.js),然后在Server.js和路由文件中统一引入。

4. React组件中select标签的onChange事件丢失

在Register组件的select标签中,onChange={this.handleUserTypeChange}被注释掉了,导致用户选择的userType无法更新到组件状态,提交时该字段为空,可能引发后端数据库插入失败。

修复:
恢复select标签的onChange事件:

<select 
  id='userType' 
  value={this.state.userType} 
  onChange={this.handleUserTypeChange} 
  className='form-control' 
  required
>
  <option value='Staff'>Staff</option>
  <option value='Player'>Player</option>
</select>

5. React组件state中重复定义username

在Register组件的constructor中,重复定义了username: '',属于代码冗余,虽然不影响功能,但需要修正:

constructor() {
  super();
  this.state = {
    username: '',
    email: '',
    password: '',
    userType: '',
    team: ''
  };
  this.handleSubmit = this.handleSubmit.bind(this);
}

6. React组件中错误状态的大小写不一致

在Register组件的team输入框中,错误状态使用了this.state.TeamError(大写T),但在validateTeam方法中设置的是teamError(小写t),导致错误提示无法正确显示:

<input 
  id='team' 
  className={`form-control ${ this.state.teamError ? 'is-invalid' : '' }`} 
  type='text' 
  onChange={this.handleTeamChange} 
  onBlur={this.validateTeam} 
  required 
/>
<div className='invalid-feedback'>{this.state.teamError}</div>

额外优化建议

  • 前端fetch请求中添加状态检查,更清晰地捕获服务器错误:
fetch('/users', {
  method: 'POST',
  body: JSON.stringify(formData),
  headers: {
    'Content-Type': 'application/json'
  }
})
.then(res => {
  if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`);
  return res.json();
})
.catch(error => console.error('Error:', error))
.then(response => console.log('Success:', response));
  • 后端可移除单独的body-parser依赖,因为Express 4.16+已内置JSON和URL编码解析中间件,直接使用app.use(express.json())和app.use(express.urlencoded())即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:28:14