79 lines
2.4 KiB
Markdown
79 lines
2.4 KiB
Markdown
# 环境与 CORS 管理
|
||
|
||
跨前后端技术栈管理环境变量、API URL 和 CORS 配置的模式。
|
||
|
||
---
|
||
|
||
## 标准环境模式
|
||
|
||
```
|
||
# .env.local(被 gitignore,用于本地开发)
|
||
NEXT_PUBLIC_API_URL=http://localhost:3001
|
||
NEXT_PUBLIC_WS_URL=ws://localhost:3001
|
||
|
||
# 预发布环境(在 Vercel/CI 中设置)
|
||
NEXT_PUBLIC_API_URL=https://api-staging.example.com
|
||
|
||
# 生产环境(在 Vercel/CI 中设置)
|
||
NEXT_PUBLIC_API_URL=https://api.example.com
|
||
```
|
||
|
||
---
|
||
|
||
## 环境变量规则
|
||
|
||
```
|
||
✅ API 基础地址来自环境变量——绝不硬编码
|
||
✅ 客户端变量前缀使用 NEXT_PUBLIC_(Next.js)或 VITE_(Vite)
|
||
✅ 后端 URL = 仅服务端使用的环境变量(用于 SSR 调用,不暴露给浏览器)
|
||
✅ 后端 CORS:按环境明确列出允许的域名列表
|
||
|
||
❌ 生产构建中绝不使用 localhost URL
|
||
❌ 绝不使用 NEXT_PUBLIC_ 前缀暴露仅后端使用的密钥
|
||
❌ 绝不提交 .env.local(提交含占位符的 .env.example)
|
||
```
|
||
|
||
---
|
||
|
||
## CORS 配置
|
||
|
||
```typescript
|
||
// 后端:感知环境的 CORS
|
||
const ALLOWED_ORIGINS = {
|
||
development: ['http://localhost:3000', 'http://localhost:5173'],
|
||
staging: ['https://staging.example.com'],
|
||
production: ['https://example.com', 'https://www.example.com'],
|
||
};
|
||
|
||
app.use(cors({
|
||
origin: ALLOWED_ORIGINS[process.env.NODE_ENV || 'development'],
|
||
credentials: true, // 需要用于 cookie(身份认证)
|
||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
|
||
}));
|
||
```
|
||
|
||
---
|
||
|
||
## 常见问题
|
||
|
||
### 问题 1:「浏览器报 CORS 错误,但 Postman 能正常访问」
|
||
|
||
**原因:** CORS 是浏览器的安全机制。Postman/curl 会跳过它。
|
||
|
||
**修复方法:**
|
||
1. 后端必须返回 `Access-Control-Allow-Origin: https://your-frontend.com`
|
||
2. 涉及 Cookie/身份认证时,两端都需要设置 `credentials: true`
|
||
3. 确认预检 `OPTIONS` 请求返回了正确的响应头
|
||
|
||
### 问题 2:「浏览器中环境变量为 undefined」
|
||
|
||
**原因:** 缺少客户端访问所需的 `NEXT_PUBLIC_` 或 `VITE_` 前缀。
|
||
|
||
**修复方法:** 客户端变量必须带有框架前缀。添加新环境变量后需要重新构建(它们在构建时被嵌入)。
|
||
|
||
### 问题 3:「本地能正常工作,预发布环境却失败」
|
||
|
||
**原因:** 域名不同,缺少预发布域的 CORS 配置。
|
||
|
||
**修复方法:** 将预发布域名添加到 `ALLOWED_ORIGINS`,确认部署平台已设置相应的环境变量。
|