You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js+MySQL全栈项目部署后CORS及503错误求助

问题

将基于Node.js、React、MySQL的全栈项目部署至生产环境,后端部署到Railway、前端部署到Netlify后,前端出现以下错误:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://mysql-------railway.app/films. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 503.

直接访问后端域名显示Railway错误页,提示“Application failed to respond”。已检查所有环境变量并添加CORS相关代码,但问题仍未解决,附后端及前端代码求解决办法。


后端代码(server/index.js)

import express from "express";
import mysql from "mysql";
import cors from "cors";
import dotenv from "dotenv";

dotenv.config();

const app = express();

app.use(
  cors({
    origin: "---frontend domain---",
    methods: ["GET", "POST", "PUT", "DELETE"],
    allowedHeaders: ["Content-Type"],
    credentials: true,
  })
);

app.options("*", cors());

const urlDB = `mysql://${process.env.MYSQLUSER}:${process.env.MYSQLPASSWORD}@${process.env.MYSQLHOST}:${process.env.MYSQLPORT}/${process.env.MYSQLDATABASE}`;

const db = mysql.createConnection(urlDB);

app.use(express.json());

app.use(cors());

app.get("/films", (req, res) => {
  const q = "SELECT * FROM films";
  db.query(q, (err, data) => {
    if (err) return res.json(err);
    return res.json(data);
  });
});

app.post("/films", (req, res) => {
  const q =
    "INSERT INTO films(`title`, `plot`, `poster`, `rating`, `release_year`) VALUES (?)";
  const values = [
    req.body.title,
    req.body.plot,
    req.body.poster,
    req.body.rating,
    req.body.release_year,
  ];

  db.query(q, [values], (err, data) => {
    if (err) return res.json(err);
    return res.json("Film has been added successfully");
  });
});

app.delete("/films/:id", (req, res) => {
  const filmId = req.params.id;
  const q = "DELETE FROM films WHERE id = ?";

  db.query(q, [filmId], (err, data) => {
    if (err) return res.json(err);
    return res.json("Film has been removed successfully");
  });
});

app.put("/films/:id", (req, res) => {
  const filmId = req.params.id;
  const q =
    "UPDATE films SET `title` = ?, `plot` = ?, `poster` = ?, `rating` = ?, `release_year` = ? WHERE id = ?";

  const values = [
    req.body.title,
    req.body.plot,
    req.body.poster,
    req.body.rating,
    req.body.release_year,
  ];

  db.query(q, [...values, filmId], (err, data) => {
    if (err) return res.json(err);
    return res.json("Film has been updated successfully");
  });
});

const PORT = process.env.MYSQLPORT;

app.listen(PORT, () => {
  console.log("Connected to backend!");
});

前端代码(client/index.js)

import React from "react";
import { useEffect } from "react";
import { useState } from "react";
import axios from "axios";
import { Link } from "react-router-dom";

const Films = () => {
  const [films, setFilms] = useState([]);

  useEffect(() => {
    const fetchAllMovies = async () => {
      try {
        const res = await axios.get(`${process.env.REACT_APP_MYSQL_URL}/films`);
        setFilms(res.data);
      } catch (err) {
        console.log(err);
      }
    };
    fetchAllMovies();
    console.log(films);
  }, []);

  const handleDelete = async (id) => {
    try {
      await axios.delete(`${process.env.REACT_APP_MYSQL_URL}/films/` + id);
      window.location.reload();
    } catch (err) {
      console.log(err);
    }
  };

  return (
    <div>
      <h1>Films</h1>
      <div>
        {films.map((film) => (
          <div key={film.id}>
            <h2>{film.title}</h2>
            {film.poster === null ? (
              <> </>
            ) : (
              <img width={50} height={80} src={film.poster} />
            )}
            <p>{film.plot}</p>
            <p>{film.release_year}</p>
            <p>{film.rating}</p>
            <button onClick={() => handleDelete(film.id)}>Delete movie</button>
            <button>
              <Link to={`/update/${film.id}`}>Update</Link>
            </button>
          </div>
        ))}
      </div>
    </div>
  );
};

export default Films;

解决办法

1. 修复后端端口配置错误

当前用process.env.MYSQLPORT作为后端服务监听端口,这是数据库端口(默认3306),Railway部署的后端需要监听平台分配的端口,该端口存在process.env.PORT变量中:

// 替换原端口定义
const PORT = process.env.PORT || 3001; // 本地开发用3001,生产环境用Railway分配的端口

2. 移除重复的CORS配置

代码中先后调用了两次app.use(cors()),第二次无参数的默认配置会覆盖第一次的自定义规则,导致origin等设置失效,删除第二次的app.use(cors());即可。

3. 添加数据库连接错误处理

当前代码未处理数据库连接失败的情况,若数据库连接失败会导致后端服务无响应,添加连接回调:

const db = mysql.createConnection(urlDB);

db.connect((err) => {
  if (err) {
    console.error('数据库连接失败:', err);
    return;
  }
  console.log('数据库连接成功');
});

4. 验证环境变量配置

  • Railway后端:确认MYSQLUSER、MYSQLPASSWORD、MYSQLHOST、MYSQLPORT、MYSQLDATABASE完全匹配Railway提供的MySQL实例信息;origin配置中的前端域名需替换为Netlify分配的实际域名。
  • Netlify前端:确认REACT_APP_MYSQL_URL设置为Railway后端的完整域名(如https://mysql-------railway.app),不要加结尾斜杠。

5. 测试后端服务

修改代码重新部署到Railway后,直接访问https://your-backend-domain/films,若返回JSON数据或数据库错误信息,说明后端已正常响应;若仍显示Railway错误页,查看Railway日志排查启动报错(如端口占用、数据库连接失败)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 06:15:07