React与Node.js中POST请求遭CORS拦截问题求助
问题背景
我是后端编程新手,尝试将React状态变量中的表单数据通过Axios发送到Node.js后端,借助Nodemailer发送邮件,但遇到了跨域和404错误。
前端代码
const handleSubmit = async () => { try { await axios.post( "http://localhost:2525/send_mail", { state } ); } catch (error) { console.log(error); } };
后端代码
const express = require('express'); const bodyParser = require('body-parser'); const cors = require('cors'); const nodemailer = require('nodemailer'); require('dotenv').config(); const app = express(); app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); app.use(cors()); app.options('',cors()); app.get('/', (req, res) => { res.send('Server is running'); }); app.post("/send_mail", cors(), async (req, res) => { let { state } = req.body; const transport = nodemailer.createTransport({ service: 'gmail', auth: { user: 'adress@mail.com', pass:'password' } }); await transport.sendMail({ from: '<myemail.@example.com>', to: "reciever@example.com", subject: "test email", html: `<div><p>${state.Message}</p></div>` }); }); app.listen(process.env.PORT || 2525, () => { console.log("Server is running"); });
State结构
const data = { FirstName: "", LastName: "", Message:"", };
遇到的问题
- 初始状态:访问
localhost:2525服务器正常,但提交表单时控制台报错,同时服务器崩溃:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:2525/send_mail. (Reason: CORS request did not succeed). Status code: (null).
- 添加proxy后:在React项目
package.json中添加"proxy": "http://localhost:2525",服务器不再崩溃,但POST请求返回404:
POSThttp://localhost:2525/send_mail Referrer Policystrict-origin-when-cross-origin
已尝试更换Chrome浏览器、排查端口占用,问题仍未解决。
解决方案
1. 修复CORS配置
后端中app.options('',cors());的空路径会导致预检请求处理异常,改为允许所有路径的预检请求:
app.options('*', cors());
同时去掉app.post("/send_mail", cors(), ...)中的重复cors()中间件,全局app.use(cors())已足够处理跨域。
2. 捕获Nodemailer异常,避免服务器崩溃
服务器崩溃的核心原因是邮件发送错误未被捕获,添加try/catch块并返回前端响应:
app.post("/send_mail", async (req, res) => { try { let { state } = req.body; const transport = nodemailer.createTransport({ service: 'gmail', auth: { user: process.env.EMAIL_USER, // 改用环境变量,不要硬编码账号密码 pass: process.env.EMAIL_PASS } }); await transport.sendMail({ from: 'myemail@example.com', // 去掉格式错误的尖括号和多余点 to: "reciever@example.com", subject: "test email", html: `<div><p>${state.Message}</p></div>` }); res.status(200).send('邮件发送成功'); } catch (error) { console.error('邮件发送失败:', error); res.status(500).send('邮件发送失败'); } });
注意:Gmail需要开启低安全性应用访问,或启用2FA后使用应用专用密码,否则会认证失败。
3. 修复Proxy后的404问题
使用React proxy配置时,前端Axios请求需改为相对路径,无需写完整域名:
const handleSubmit = async () => { try { await axios.post( "/send_mail", // 改为相对路径 { state } ); } catch (error) { console.log(error); } };
修改package.json后需重启React开发服务器,确保proxy配置生效。
4. 验证请求数据格式
如果前端状态变量是data,建议直接发送data而非包裹在state对象中,避免后端解析失败:
// 前端修改 await axios.post("/send_mail", data); // 后端对应修改 let { FirstName, LastName, Message } = req.body;
验证步骤
- 重启Node.js后端服务器
- 重启React开发服务器
- 查看浏览器控制台的请求状态与响应
- 检查后端控制台日志,确认是否存在错误
内容的提问来源于stack exchange,提问作者Danilo Vukovic

