React前端POST提交数据无法写入MySQL数据库问题排查
注册数据无法写入MySQL排查结果
以下是代码中存在的直接导致写入失败的问题,按优先级排序:
前端问题
- 最高优先级问题:请求地址配置错误。Axios写的目标地址为
http://localhost3000/register,存在两处错误:一是localhost和端口号之间缺少冒号分隔,二是后端服务实际监听的是3001端口而非3000,请求根本没有发送到你启动的Express服务上,自然不会触发数据库写入逻辑。 - 表单默认提交行为未拦截。注册按钮放在
<form>标签内部,点击时会触发表单默认的提交刷新行为,页面会在Axios请求发送完成前直接刷新,请求被强制中断,这也是你在控制台、网络面板看不到明确报错的核心原因之一。 - 文件上传逻辑错误。
type="file"类型的输入框通过e.target.value只能拿到本地文件的伪路径,无法获取真实文件对象;且文件传输不能用默认的JSON格式,必须用FormData包装请求体,同时配置对应的请求头。 - 优化点:密码输入框当前用的是
type="text",会明文显示输入内容,正式使用请改为type="password"。
前端修正代码
import React, { useState } from 'react'; import './register.css'; import {Link} from 'react-router-dom'; import Image from '../../assets/Image.png'; import Axios from 'axios'; const Register = () => { const [uploadReq, setUploadReq] = useState('') const [usernameReq, setUsernameReq] = useState('') const [fullnameReq, setFullnameReq] = useState('') const [emailReq, setEmailReq] = useState('') const [passwordReq, setPasswordReq] = useState('') const registration = (e) => { // 阻止表单默认提交刷新 e.preventDefault(); // 传文件必须用FormData包装 const formData = new FormData(); formData.append('upload', uploadReq); formData.append('username', usernameReq); formData.append('fullname', fullnameReq); formData.append('email', emailReq); formData.append('password', passwordReq); // 修正请求地址:补全冒号、改为后端实际监听的3001端口 Axios.post("http://localhost:3001/register", formData, { headers: { 'Content-Type': 'multipart/form-data' } }).then((response) => { console.log(response); }); }; return ( <div className='register section__padding'> <div className="register-container"> <h1>register</h1> <p className='upload-file'>Upload Profile pic</p> <div className="upload-img-show"> <img src={Image} alt="banner" /> <p>browse media on your device</p> </div> <form className='register-writeForm' autoComplete='off' > <div className="register-formGroup"> <label>Upload</label> <input type="file" className='custom-file-input' onChange={(e) => { // 修正文件取值逻辑,取选中的第一个文件对象 setUploadReq(e.target.files[0]); }} /> </div> <div className="register-formGroup"> <label>Full Name</label> <input type="text" placeholder='Name' onChange={(e) => { setFullnameReq(e.target.value); }} /> </div> <div className="register-formGroup"> <label>Username</label> <input type="text" onChange={(e) => { setUsernameReq(e.target.value); }}placeholder='Username' /> </div> <div className="register-formGroup"> <label>Email</label> <input type="email" placeholder='Email' onChange={(e) => { setEmailReq(e.target.value); }} /> </div> <div className="register-formGroup"> <label>Password</label> {/* 优化:密码框改为password类型 */} <input type="password" onChange={(e) => { setPasswordReq(e.target.value); }} placeholder='Password' /> </div> <div className="register-button"> <button className='register-writeButton' onClick={registration}>register</button> <Link to="/login"> <button className='reg-login-writeButton' >Login</button> </Link> </div> </form> </div> </div> ) }; export default Register;
后端问题
- 缺少文件上传解析能力。当前仅配置了
express.json()中间件处理JSON格式请求体,无法解析multipart/form-data类型的文件请求,拿不到upload字段内容。 - 接口无响应返回。数据库操作无论成功失败都没有给前端返回HTTP响应,前端无法感知请求结果,也不利于问题定位。
- 数据库异常未做流程中断处理,出错后逻辑会继续向下执行,容易产生脏数据。
- 优化点:密码明文存储存在严重安全风险,正式环境请使用bcrypt等库对密码做哈希加密后再存入数据库。
后端修正代码
先安装文件解析依赖:npm i multer
const express = require("express"); const app = express(); const mysql = require("mysql"); const cors = require("cors"); // 引入文件上传解析中间件 const multer = require('multer'); // 配置上传文件存储路径 const upload = multer({ dest: 'uploads/' }) app.use(express.json()); app.use(cors()); // 静态化上传目录,方便前端直接访问上传的头像文件 app.use('/uploads', express.static('uploads')); const db = mysql.createPool({ host: "localhost", user: "root", password: "xyz", database: "nftdatabase", }); // 注册接口增加文件解析中间件处理upload字段 app.post('/register', upload.single('upload'), (req, res) => { // 拿到上传后的文件访问路径 const uploadPath = req.file ? `/uploads/${req.file.filename}` : ''; const Fullname = req.body.fullname const Username = req.body.username const Email = req.body.email const Password = req.body.password db.query("INSERT INTO user (upload, fullname, username, email, password) VALUES (?,?,?,?,?)", [uploadPath, Fullname, Username, Email, Password], (err, result) => { if(err){ console.log(err); // 出错时返回错误响应并中断流程 return res.status(500).send({code: 500, msg: '注册失败', error: err.message}); } // 操作成功返回正常响应 res.send({code: 200, msg: '注册成功', data: result}); }); }); app.listen(3001, () => { console.log("running on port 3001"); });
验证步骤
- 先启动后端服务,确认控制台打印
running on port 3001 - 启动前端服务,填写表单点击注册,此时页面不会刷新
- 打开Chrome网络面板找到register请求,确认请求地址为
http://localhost:3001/register,状态码为200 - 查看后端控制台,如果没有打印SQL错误,直接查询MySQL的user表即可看到插入的注册数据
- 如果仍写入失败,直接看后端控制台打印的err信息,常见问题包括表字段名不匹配、字段类型不兼容、数据库连接配置错误、表不存在等,都会在错误信息中明确说明。
内容的提问来源于stack exchange,提问作者Steve1101
相关产品推荐
相关产品推荐

