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

React前端+Node后端部署Vercel后CORS策略错误求助

Vercel部署后Node.js后端CORS配置失效问题解决方案

问题描述

本地环境下React前端调用Node.js后端API正常,但部署到Vercel后,出现CORS错误:

Access to XMLHttpRequest at 'https://portfolio-5-0-backend.vercel.app/api/send-email' from origin 'https://portfolio-5-0-frontend.vercel.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

用户当前CORS配置及前端API调用代码如下:

后端CORS配置

const allowedOrigins = ["https://portfolio-5-0-frontend-2c3fpno4h-kroplewskims-projects.vercel.app", "https://portfolio-5-0-frontend.vercel.app"];

const corsOptions = {
  origin: function (origin, callback) {
    if (!origin || allowedOrigins.indexOf(origin) !== -1) {
      callback(null, { origin: true });
    } else {
      callback(new Error("Not allowed by CORS"));
    }
  },
  methods: ["GET", "POST", "PUT", "PATCH", "DELETE"],
  allowedHeaders: ["Access-Control-Allow-Origin", "Origin", "X-Requested-With", "Content-Type", "Accept", "Authorization"],
  credentials: false,
};

app.options("*", cors(corsOptions));
app.use(cors(corsOptions));
app.use(bodyParser.json());

前端API调用代码

const onSubmit = handleSubmit(async (data) => {
  try {
    PushNotification("Sending email...", "bg-info");
    const response = await axios.post("https://portfolio-5-0-backend.vercel.app/api/send-email", {
      Email: data.Email,
      Name: data.Name,
      Message: data.Message,
    }, {
      withCredentials: true,
      headers: {
        'Content-Type': 'application/json',
      },
    });
    if (response.status === 200) {
      PushNotification("Email sent successfully!...", "bg-success");
    }
  } catch (e) {
    PushNotification("Failed to send email", "bg-error");
    console.log(e);
  }
});

解决方案

1. 修正CORS配置的核心问题

  • origin回调格式错误:原代码返回{ origin: true }不符合cors中间件要求,应直接返回true或匹配的origin值。
  • allowedHeaders冗余配置:Access-Control-Allow-Origin是后端响应头,无需加入请求允许的headers列表。
  • credentials不匹配:前端设置withCredentials: true,后端需同步设置credentials: true,二者保持一致。

修正后的CORS配置:

const allowedOrigins = ["https://portfolio-5-0-frontend-2c3fpno4h-kroplewskims-projects.vercel.app", "https://portfolio-5-0-frontend.vercel.app"];

const corsOptions = {
  origin: function (origin, callback) {
    if (!origin || allowedOrigins.includes(origin)) {
      callback(null, true);
    } else {
      callback(new Error("Not allowed by CORS"));
    }
  },
  methods: ["GET", "POST", "PUT", "PATCH", "DELETE"],
  allowedHeaders: ["Origin", "X-Requested-With", "Content-Type", "Accept", "Authorization"],
  credentials: true,
};

// 保持中间件顺序:先处理OPTIONS请求,再应用CORS,最后解析请求体
app.options("*", cors(corsOptions));
app.use(cors(corsOptions));
app.use(bodyParser.json());

2. 同步前端withCredentials配置

若后端设置credentials: false,需将前端的withCredentials: true改为false,避免凭证不匹配:

const response = await axios.post("https://portfolio-5-0-backend.vercel.app/api/send-email", {
  Email: data.Email,
  Name: data.Name,
  Message: data.Message,
}, {
  withCredentials: false,
  headers: {
    'Content-Type': 'application/json',
  },
});

3. 适配Vercel Serverless函数场景

如果后端是Vercel Serverless函数(如api/send-email.js),需确保中间件正确挂载:

import cors from 'cors';
import express from 'express';
import bodyParser from 'body-parser';

const app = express();
const allowedOrigins = ["https://portfolio-5-0-frontend-2c3fpno4h-kroplewskims-projects.vercel.app", "https://portfolio-5-0-frontend.vercel.app"];

const corsOptions = {
  origin: (origin, callback) => {
    if (!origin || allowedOrigins.includes(origin)) {
      callback(null, true);
    } else {
      callback(new Error('Not allowed by CORS'));
    }
  },
  credentials: true,
};

app.use(cors(corsOptions));
app.use(bodyParser.json());

app.post('/', async (req, res) => {
  // 邮件发送逻辑
  res.status(200).json({ message: 'Email sent successfully' });
});

export default app;

4. 强制刷新Vercel部署缓存

Vercel可能缓存旧构建产物,导致新配置未生效。在Vercel控制台找到后端项目,进入Deployments选择最新部署,点击Redeploy并勾选Clear build cache & deploy后重新部署。

5. 验证环境变量配置(若使用)

如果allowedOrigins从环境变量读取,需确保Vercel控制台的环境变量已正确设置,且部署时选择对应环境。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 20:25:03