使用Fetch API时React表单数据无法与Node.js服务器交互的问题排查
嘿,别担心,新手遇到这种问题太正常了!咱们一步步来排查,其实就是几个小细节没注意到:
首先看后端代码的问题
你现在的路由写法有两个关键错误,直接导致服务器根本没收到请求:
app.post的路径应该用相对路径,不是完整的URL(比如/dashboard/而不是http://localhost:5000/dashboard/)- 语法错误:你把路由的括号打错位置了,回调函数没有被正确传入
app.post里,相当于这个路由根本没注册成功
修改后的后端代码:
const express = require("express"); const app = express(); const cors = require("cors"); //middleware app.use(cors()); app.use(express.json()); // 修正路由路径和语法,同时加上响应避免请求挂起 app.post("/dashboard/", (req, res) => { console.log('i got a message'); console.log(req.body); // 给前端返回响应,不然浏览器会一直等待 res.status(200).json({ status: "success", data: req.body }); }) app.listen(5000, () => { console.log(`Server is starting on port 5000`); });
再看前端代码的几个小问题
- message输入框类型错误:HTML里没有
input type="textarea",应该用<textarea>标签,不然这个输入框的绑定会出问题,值可能无法正确获取 - fetch异步处理不完整:你用了
async但没加await,而且fetch默认不会把HTTP错误(比如404、500)抛进catch,需要手动检查响应状态 - React语法细节:按钮的
class要改成className,这是React的规范;另外onChange可以直接写onChange={onChange},不用额外包一层箭头函数
修改后的前端代码:
import React, { Fragment, useState } from "react"; const EmailForm = () => { const [inputs, setInputs] = useState({ email: "", subject: "", message: "", }); const { email, subject, message } = inputs; const onChange = e => setInputs({ ...inputs, [e.target.name]: e.target.value }); const onSubmitForm = async e => { e.preventDefault(); try { const test = { email, subject, message }; const options = { method: 'POST', headers: { "Content-type": "application/json", jwt_token: localStorage.token }, body: JSON.stringify(test) }; // 用await处理异步请求,同时检查响应状态 const response = await fetch("http://localhost:5000/dashboard/", options); if (!response.ok) { throw new Error(`请求失败!状态码:${response.status}`); } const result = await response.json(); console.log('提交成功:', result); console.log('表单数据:', test); } catch (err) { console.error('提交出错:', err.message); } }; return ( <Fragment> <form onSubmit={onSubmitForm}> <input type="text" name="email" placeholder="email" value={email} onChange={onChange} className="form-control my-3" /> <input type="text" name="subject" placeholder="subject" value={subject} onChange={onChange} className="form-control my-3" /> {/* 替换为正确的textarea标签 */} <textarea name="message" placeholder="message" rows="10" cols="50" value={message} onChange={onChange} className="form-control my-3" /> {/* 把class改为className */} <button className="btn btn-success btn-block">Submit</button> </form> </Fragment> ); }; export default EmailForm;
为什么之前没有日志输出?
核心原因是后端路由的语法错误,导致服务器根本没监听/dashboard/的POST请求,所以点击提交后,服务器完全没收到请求,自然没有日志。同时前端的输入框错误和fetch处理不完整,也会导致就算服务器修复了,数据也可能没正确发送。
现在把前后端代码替换后,重启服务器,再测试提交,应该就能看到控制台的日志啦!
内容的提问来源于stack exchange,提问作者Oran_Cowell
相关产品推荐
相关产品推荐

