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

已配置域名仍遭CORS策略拦截,全栈项目部署故障求助

部署后CORS异常与数据库更新不稳定问题排查求助

项目背景

  • 前端:React+Vite,部署在Vercel,地址 https://mywebsite.ca
  • 后端:Express+Node,部署在Vercel,地址 https://backend.vercel.app
  • 数据库:AWS RDS托管MySQL

问题现象

  • 登录/注册功能正常(极少出现服务器错误),无CORS问题;但用户登录后进入 https://mywebsite.ca/course-selection 页面时,频繁触发CORS拦截
  • 已配置CORS,但仍频繁收到以下错误:
    Access to XMLHttpRequest at 'https://backend.vercel.app/backend/courseChange/' from origin 'https://www.mywebsite.ca' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
    
    伴随 Failed to load resource: net::ERR_FAILED 错误
  • 网络监控到两种失败请求:
    1. POST请求到 https://backend.vercel.app/backend/courseChange/,Payload格式正确,但触发CORS拦截
    2. OPTIONS请求到同一地址,返回500 Internal Server Error

已配置的后端CORS代码

import express from "express"
import cors from "cors"
import userRoutes from "./routes/users.js"
import authRoutes from "./routes/auth.js"
import courseChangeRoutes from "./routes/courseChange.js"
import cookieParser from "cookie-parser";

const app = express();
app.use(express.json());
app.use(cookieParser());

app.use(
    cors({
      origin: 'https://www.mywebsite.ca',
      methods: ['GET', 'POST', 'OPTIONS', 'PUT', 'DELETE'],
      credentials: true,
    })
);

app.use((req, res, next) => {
  res.header("Access-Control-Allow-Credentials", true);
  next();
});

app.use("/backend/users", userRoutes);
app.use("/backend/auth", authRoutes);
app.use("/backend/courseChange", courseChangeRoutes);

相关业务代码

后端课程更新逻辑(operation/courseChange.js)

export const courseChange = async (req, res) => {
    const { userId, courses_ids, term } = req.body;

    if (!userId || !Array.isArray(courses_ids) || !term) {
        return res.status(400).send('Invalid input');
    }

    const maxCourses = 15; 

    try {
        // Clear existing courses for the specified term
        let clearQuery = 'UPDATE users SET ';
        for (let i = 1; i <= maxCourses; i++) {
            clearQuery += `${term}Course${i} = NULL, `;
        }
        clearQuery = clearQuery.slice(0, -2) + ' WHERE id = ?';
        console.log('Clear Query:', clearQuery, [userId]);
        await db.execute(clearQuery, [userId]);

        // Construct the update query for new courses
        let updateQuery = 'UPDATE users SET ';
        const updateValues = [];
        if (courses_ids.length > 0) {
            courses_ids.forEach((courseId, index) => {
                updateQuery += `${term}Course${index + 1} = ?, `;
                updateValues.push(courseId);
            });
            updateQuery = updateQuery.slice(0, -2);
            updateQuery += ' WHERE id = ?';
            updateValues.push(userId);

            console.log('Update Query:', updateQuery, updateValues);
            await db.execute(updateQuery, updateValues);
            res.status(200).send('Courses updated successfully');
        }

    } catch (error) {
        console.error('Error updating courses:', error);
        res.status(500).send('Error updating courses: ' + error.message);
    }
    
};

前端请求逻辑(pages/course-selection.jsx)

import { useState, useEffect } from 'react';
import LeftMenu from '/src/components/leftMenu';
import Calendar from '/src/components/calendar';
import Nav from '/src/components/nav';
import Selection from '/src/components/selections';
import fallJSON from '/src/assets/fall_2024_0626.json';
import winterJSON from '/src/assets/winter_2025_0626.json';
import axios from 'axios'

axios.defaults.withCredentials = true;

export default function Courses() {

    const [fallCourses, setFallCourses] = useState([]);
    const [winterCourses, setWinterCourses] = useState([]);
    const [fallData, setFallData] = useState(fallJSON);
    const [winterData, setWinterData] = useState(winterJSON);
    const [err, setError] = useState(null);

    const updateFallCourses = async (courses_ids) => {
        // Prepare for Calendar Rendering
        const courses = courses_ids.flatMap(course => fallData[course].slice(2));
        setFallCourses(courses);
        // Send data to backend
        const user = JSON.parse(localStorage.getItem('user'));
        const userId = user ? user.id : null;
        const term = "fall"
        try {
            await axios.post('https://backend.vercel.app/backend/courseChange/', {
                userId,
                courses_ids,
                term,
            }, {
                headers: {
                    'Access-Control-Allow-Origin': '*',
                    'Content-Type': 'application/json',
                }
            });
            console.log('Courses updated successfully');
        } catch (err) {
            const errorMessage = err.response?.data?.message || "An unexpected error occurred";
            setError(errorMessage);
        }

    };

// 此处存在逻辑类似的updateWinterCourses函数

异常表现

调用updateFallCourses时会随机出现三种情况:

  1. 控制台打印CORS和ERR错误,无任何操作生效
  2. 无错误提示,控制台显示“Courses updated successfully”,数据库更新正常
  3. 无错误提示,控制台显示成功信息,但数据库未更新

本地环境(前端http://localhost:3000,后端http://localhost:8800)下功能完全正常,无CORS问题

求助需求

  • 急需排查解决CORS异常和数据库更新不稳定的问题,计划1-2天内上线
  • 欢迎针对代码优化、项目管理的建议(首次开发全栈项目)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 19:38:11