Node.js端点重复接收数据且响应未返回的问题求助
问题解决:React与Node.js交互的两个异常问题
问题1:Node.js终端两次打印请求数据
原因
- React 18的**严格模式(Strict Mode)**在开发环境下会重复执行
useEffect这类生命周期函数,导致axios发送了两次POST请求,终端因此两次打印数据。 - 服务器未正确处理CORS预检的OPTIONS请求,这虽不直接引发两次POST,但会埋下CORS相关的潜在问题。
解决方案
- 调试时可临时关闭React严格模式:在项目入口文件(如
main.jsx)中移除<StrictMode>标签。 - 服务器端添加OPTIONS请求处理,统一配置CORS(推荐):
// 手动处理OPTIONS预检请求 app.options('/api/data', (req, res) => { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, POST'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); res.setHeader('Access-Control-Max-Age', 2592000); res.sendStatus(200); }); // 更简便的方式是使用cors包 // const cors = require('cors'); // app.use(cors());
问题2:服务器响应未返回至客户端
原因
客户端代码尝试获取response.data.message,但服务器返回的是纯字符串(res.json(data)会将字符串转为JSON格式),而非包含message属性的对象,导致response.data.message为undefined,页面无法显示内容。
解决方案
两种方式二选一即可:
- 修改服务器返回格式,返回带
message属性的对象:const data = "Response from POST request: " + formData.firstName + " " + formData.surname; res.json({ message: data }); // 返回包含message的对象 - 修改客户端取值逻辑,直接使用返回的字符串:
.then(response => { setData(response.data); // 直接读取返回的字符串 })
修正后的React组件代码
'use client'; import React, { useEffect, useState } from 'react'; import axios from 'axios'; function callApi() { const [data, setData] = useState(''); useEffect(() => { axios.post('http://localhost:3001/api/data', {firstName: 'Fred', surname: 'Bloggs'}, {headers: {'Content-Type': 'multipart/form-data'}}) .then(response => { // 对应服务器返回的对象格式,读取message属性 setData(response.data.message); }) .catch(error => { console.error(error); }); }, []); return ( <div className="App"> <h1>React and Node.js Integration</h1> <p>Message from the server: {data}</p> </div> ); } export default callApi;
修正后的Node.js服务器代码
const express = require('express'); const app = express(); const port = 3001; const multer = require('multer'); const upload = multer(); // 处理OPTIONS预检请求 app.options('/api/data', (req, res) => { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, POST'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); res.setHeader('Access-Control-Max-Age', 2592000); res.sendStatus(200); }); app.post('/api/data', upload.none(), (req, res) => { const formData = req.body; console.log('form data', formData); res.setHeader('Access-Control-Allow-Origin', '*'); const data = "Response from POST request: " + formData.firstName + " " + formData.surname; res.json({ message: data }); // 返回带message属性的对象 }); app.listen(port, () => { console.log(`Server is running on port ${port}`); });
内容的提问来源于stack exchange,提问作者w0051977
相关产品推荐
相关产品推荐

