如何在 MERN 中修复 CORS 错误(安全方式)
Source: Dev.to
为什么会出现这种情况?
这不是 bug,而是一个特性。
浏览器内置了一种安全机制,称为 同源策略(Same‑Origin Policy)。它的作用是防止一个网页上的恶意脚本获取另一个网页上的敏感数据。
在典型的本地 MERN 栈配置中:
- 你的 React 前端运行在
http://localhost:3000 - 你的 Node/Express 后端运行在
http://localhost:5000
对浏览器而言,这些不同的端口使它们成为完全独立的 源(origin)。浏览器并不知道这两个端口都是你拥有的。它看到一个陌生的请求试图与你的服务器通信,于是阻止该请求以保护你。
解决方案:将前端加入白名单
要解决这个问题,需要告诉 Express 服务器:“没问题,这个运行在 3000 端口的前端是我的”。我们通过跨域资源共享(CORS)头来实现。管理 CORS 最简便的方式是使用 cors 中间件包。
步骤 1:安装包
在终端中进入你的 后端(服务器) 文件夹,运行:
npm install cors
步骤 2:配置服务器
打开你的主服务器文件(通常是 index.js 或 server.js)。在定义路由之前导入 cors 并使用它。
代码如下:
const express = require('express');
const cors = require('cors');
const app = express();
// The Magic Lines 👇
app.use(cors({
origin: 'http://localhost:3000', // 只允许你的前端
credentials: true // 如果使用 cookie / session 必须
}));
app.use(express.json());
// Your routes go here...
// app.use('/api/users', userRoutes);
app.listen(5000, () => {
console.log('Server running on port 5000');
});
将 origin 设置为 http://localhost:3000 后,服务器会向浏览器发送正确的响应头,浏览器就会放行数据。
⚠️ 关键的生产环境警告
深夜调试时,你可能会在 StackOverflow 上看到有人建议直接使用:
// DANGER ZONE
app.use(cors());
虽然这能解决错误,但它的做法是允许 互联网上的任何网站 向你的 API 发起请求。这在本地快速测试时可以接受,但 绝不能在生产环境中使用,否则会留下巨大的安全漏洞。
在生产环境中,始终使用环境变量来保存前端 URL,以确保安全:
app.use(cors({
origin: process.env.FRONTEND_URL, // 例如 'https://myapp.com'
}));
总结
- CORS 产生的原因是前端和后端运行在不同的端口/域名上。
- 通过在后端安装
cors并将其配置为只允许特定的前端来源即可解决。 - 绝不要在生产环境中使用宽松的
app.use(cors()),一定要限制允许的来源。