You need to enable JavaScript to run this app. 求助:React+Node.js应用部署Heroku后axios POST请求报405错误
优惠活动
大模型
产品
解决方案
定价
更多

求助:React+Node.js应用部署Heroku后axios POST请求报405错误

问题描述
  • 开发的React+Node.js应用在本地localhost:5000环境下可正常运行,部署到Heroku后POST请求无法获取响应,仅返回405错误,已调试2天未找到解决方案。
  • Web控制台报错信息:Uncaught (in promise) Error: Request failed with status code 405
  • 完整代码可在GitHub仓库sajpanchal/portfolio查看

相关代码片段

前端aboutme.js

handleSubmit = (event) => {
    const data = { ...this.state.data };
    event.preventDefault();
    axios.post(`${BASE_API_URL}/api/email`, data).then((res) => {
      console.log(res);
      console.log(res.data);
    });
};

后端Node.jsindex.js

const express = require("express");
const bodyParser = require("body-parser");
const path = require("path");
const logger = require("morgan");

const app = express();
var nodemailer = require("nodemailer");
require("dotenv").config();

const { USER_PASSWORD, USER_EMAIL, RECEIVER_EMAIL } = process.env;
console.log(USER_PASSWORD);
// React生产构建配置
app.use(express.static(path.join(__dirname, "build"))); // 从build目录提供所有静态文件

app.use(logger("dev"));

app.get("/", (req, res) => {
  res.sendFile(path.join(__dirname, "build", "index.html")); // 保证客户端路由功能正常
});

app.use(bodyParser.json());
// 允许应用与不同服务器上的服务交互

// 设置HTTP响应头
app.use((req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader(
    "Access-Control-Allow-Methods",
    "GET, POST, PUT, PATCH, DELETE"
  );
  res.setHeader("Acess-Control-Allow-Headers", "Content-Type , Authorization");
  next();
});
// GET请求
app.get("/api", (req, res, next) => {
  res.send("API status: OK");
});

var transporter = nodemailer.createTransport({
  service: "gmail",
  auth: {
    user: USER_EMAIL,
    pass: USER_PASSWORD,
  },
});

app.post("/api/email", (req, res, next) => {
  var mailOptions = {
    from: req.body.email,
    to: RECEIVER_EMAIL,
    subject: req.body.subject,
    html: `<strong>sender: ${req.body.email}</strong><br>Message: <strong>${req.body.message}</strong>`,
  };

  transporter.sendMail(mailOptions, function (error, info) {
    if (error) {
      res.status(400).json({
        error: error,
      });
    } else {
      res.status(200).json({
        success: true,
      });
    }
  });
});

const port = process.env.PORT || 5000;
app.listen(port, "0.0.0.0");
console.log("connected to port: ", port);

补充说明

  • 项目结构:将Node.js后端集成到React项目根目录,已生成React生产构建版本用于部署。
  • 附运行错误截图、Heroku运行日志截图用于排查。
解决方案
  • 检查package.json配置
    • 确保start脚本指向Node服务而非静态文件服务,正确示例:"start": "node index.js"
    • 新增engines字段指定兼容的Node版本,避免Heroku默认版本不兼容,示例:
    "engines": {
      "node": "16.x"
    }
    
  • 调整Express中间件顺序与配置
    • 修正CORS响应头拼写错误:Acess-Control-Allow-Headers改为Access-Control-Allow-Headers,同时修正头值的格式问题:Content-Type , Authorization改为Content-Type, Authorization
    • 将CORS处理、API路由移到静态文件服务之前,避免静态中间件优先匹配API路径,对POST请求返回405
    • 新增OPTIONS预检请求处理,避免跨域非简单请求被拦截
  • 修正前端环境变量
    • 生产环境下将BASE_API_URL配置为空字符串(同源场景),不要写死本地localhost:5000地址
  • 检查Heroku环境变量配置
    • 确认USER_EMAIL、USER_PASSWORD、RECEIVER_EMAIL已在Heroku后台正确配置,避免服务启动异常

内容的提问来源于stack exchange,提问作者unknown explorer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.31 01:36:07