React(Vite)+Node+Nginx部署后表单提交多类错误排查求助
问题解决方案
一、修复Node后端代码的核心错误
你的后端代码中sendEmail是异步Promise,但try块未使用await,导致不管邮件发送是否成功都会直接返回200状态码,且无法捕获邮件发送错误。修改如下:
app.post('/apply', async (req, res) => { // 添加async关键字 const { firstName, lastName, company, userEmail, userPhone } = req.body; function sendEmail(firstName, lastName, company, userEmail, userPhone) { return new Promise((resolve, reject) => { var transporter = nodemailer.createTransport({ host : 'smtp-mail.outlook.com', port : 587, secure : false, requireTLS : true, tls: { ciphers : 'TLSv1.2' }, auth: { user : emailFrom, pass : password, } }); const configs = { // 补充完整邮件配置(示例) from: emailFrom, to: '你的目标邮箱@example.com', subject: '新申请提交', text: `姓名: ${firstName} ${lastName}\n公司: ${company}\n邮箱: ${userEmail}\n电话: ${userPhone}` }; transporter.sendMail(configs, function(error, info) { if (error) { console.log(error); return reject(error); // 传递原始错误便于排查 } return resolve({message: '邮件发送成功'}); }); }); } try { await sendEmail(firstName, lastName, company, userEmail, userPhone); // 添加await res.status(200).json({msg: 'thx'}); } catch (error) { console.error('邮件发送失败:', error); res.status(500).json({ error: error.message || '发送邮件失败' }); } });
二、解决前端请求路径与混合内容问题
不要硬编码服务器IP或端口,改用相对路径自动适配当前域名的HTTP/HTTPS协议:
- 将React中的
formEndpoint改为'/apply':
const response = await fetch( '/apply', // 直接使用相对路径 { method : 'POST', body : JSON.stringify(messageContent), headers : {'Content-Type': 'application/json'} } );
- 确保React项目打包时使用生产环境配置,避免残留开发环境的
localhost配置。
三、修正Nginx代理与SSL配置
ERR_SSL_PROTOCOL_ERROR大概率是代理配置错误导致的,以下是适配certbot证书的完整Nginx配置示例:
# 强制HTTPS跳转 server { listen 80; server_name 你的域名.com; # 替换为实际域名 return 301 https://$host$request_uri; } # HTTPS服务配置 server { listen 443 ssl; server_name 你的域名.com; # certbot自动生成的证书路径,无需修改 ssl_certificate /etc/letsencrypt/live/你的域名.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/你的域名.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # React静态文件路径,替换为实际打包目录 root /var/www/你的React项目/build; index index.html; # 代理后端API请求到Node服务 location /apply { proxy_pass http://localhost:3000; # 替换为Node服务监听端口 proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 传递HTTPS协议给Node } # React单页应用路由兼容,避免刷新页面404 location / { try_files $uri $uri/ /index.html; } }
配置完成后重启Nginx:
sudo systemctl restart nginx
四、后端部署注意事项
- Node服务无需配置SSL:Nginx已处理HTTPS,Node只需监听本地端口(如3000),无需暴露给公网,防火墙也无需开放Node端口。
- 优化CORS配置:若使用Nginx代理,可移除
app.use(cors());若需保留,可限定仅允许你的域名访问:
const cors = require('cors'); app.use(cors({ origin: 'https://你的域名.com' }));
- 保障Node服务持续运行:使用
pm2或systemd管理Node进程,避免退出后服务中断。
五、排查步骤
- 验证Node服务状态:在服务器执行
curl http://localhost:3000/apply -X POST -H "Content-Type: application/json" -d '{"firstName":"test"}',确认后端能正常响应。 - 验证Nginx代理:执行
curl https://你的域名.com/apply -X POST -H "Content-Type: application/json" -d '{"firstName":"test"}',检查是否返回后端响应。 - 检查SSL证书:执行
certbot certificates,确认证书有效且未过期。 - 查看日志:通过
/var/log/nginx/error.log查看Nginx日志,或Node服务日志定位具体错误。
内容的提问来源于stack exchange,提问作者Alexandr Pushkin Aleks Last
相关产品推荐
相关产品推荐

