SERVICES_CONFIG.md
9.68 KB
🚀 ERP 系统服务启动和 CORS 配置文档
📋 系统组件概览
| 服务 | 端口 | 框架 | 状态 |
|---|---|---|---|
| 后端 API | 2011 | ASP.NET Core 6.0 | ✅ |
| 前端管理 | 3001 | Vue 3 + Vite | ✅ |
| 收银台 | 8888 | Python HTTP Server | ✅ |
🎯 快速启动
一键启动脚本(Mac/Linux)
#!/bin/bash
# 创建脚本文件: start-all.sh
cat > start-all.sh << 'SCRIPT'
#!/bin/bash
# 启动后端 (2011)
echo "启动后端 API..."
cd netcore
dotnet run --urls="http://localhost:2011" --project src/Application/NCC.API &
BACKEND_PID=$!
# 等待后端启动
sleep 10
# 启动前端 (3001)
echo "启动前端..."
cd ../antis-ncc-admin
npm run dev -- --port 3001 &
FRONTEND_PID=$!
echo ""
echo "✅ 后端 API: http://localhost:2011"
echo "✅ 前端管理: http://localhost:3001"
echo "✅ 收银台: http://localhost:8888"
echo ""
echo "后端 PID: $BACKEND_PID"
echo "前端 PID: $FRONTEND_PID"
echo ""
echo "停止服务: kill $BACKEND_PID $FRONTEND_PID"
SCRIPT
chmod +x start-all.sh
分别启动
后端启动 (2011)
cd /Users/hexiaodong/Desktop/git/erp2025/Antis.Erp.Plat/netcore
dotnet run --urls="http://localhost:2011" --project src/Application/NCC.API
前端启动 (3001)
cd /Users/hexiaodong/Desktop/git/erp2025/Antis.Erp.Plat/antis-ncc-admin
npm run dev -- --port 3001
收银台启动 (8888)
cd /Users/hexiaodong/Desktop/git/erp2025/Antis.Erp.Plat/sy
python3 -m http.server 8888
🔒 CORS 配置详解
后端 CORS 配置
文件路径: netcore/src/Application/NCC.API/appsettings.json
{
"CorsAccessorSettings": {
"PolicyName": "NCCCorsAccessor",
"WithOrigins": [
"http://192.168.0.138:8080",
"http://localhost:8080",
"http://localhost:3021",
"http://localhost:3014",
"http://localhost:3015",
"http://localhost:2011",
"http://localhost:3009",
"http://localhost:2016",
"http://localhost:3000",
"http://localhost:9528",
"http://localhost:8200",
"http://localhost:3001", // ← 前端访问源
"http://localhost:8080"
],
"WithExposedHeaders": [
"access-token",
"x-access-token",
"Content-Disposition"
]
}
}
CORS 中间件配置
文件路径: netcore/src/Application/NCC.API.Core/Startup.cs
ConfigureServices 方法
public void ConfigureServices(IServiceCollection services)
{
// ... 其他配置 ...
// 第 54 行:添加 CORS 服务
services.AddCorsAccessor();
// ... 其他配置 ...
}
Configure 方法
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ...)
{
// ... 其他中间件 ...
app.UseRouting();
// 第 197 行:应用 CORS 中间件
app.UseCorsAccessor();
// 第 199 行:JWT 认证
app.UseAuthentication();
// 第 200 行:授权检查
app.UseAuthorization();
// ... 其他中间件 ...
app.UseEndpoints(endpoints => { /* ... */ });
}
CORS 配置类
文件路径: netcore/src/Infrastructure/NCC/CorsAccessor/Options/CorsAccessorSettingsOptions.cs
public sealed class CorsAccessorSettingsOptions : IConfigurableOptions<CorsAccessorSettingsOptions>
{
/// <summary>
/// 策略名称
/// </summary>
public string PolicyName { get; set; }
/// <summary>
/// 允许来源域名,没有配置则允许所有来源
/// </summary>
public string[] WithOrigins { get; set; }
/// <summary>
/// 请求表头,没有配置则允许所有表头
/// </summary>
public string[] WithHeaders { get; set; }
/// <summary>
/// 响应标头
/// </summary>
public string[] WithExposedHeaders { get; set; }
/// <summary>
/// 设置跨域允许请求谓词,没有配置则允许所有
/// </summary>
public string[] WithMethods { get; set; }
/// <summary>
/// 跨域请求中的凭据
/// </summary>
public bool? AllowCredentials { get; set; }
/// <summary>
/// 设置预检过期时间
/// </summary>
public int? SetPreflightMaxAge { get; set; }
}
🌐 跨域请求流程
简单请求流程(GET 等)
前端 (3001)
↓
Origin: http://localhost:3001
↓
后端 (2011)
↓
检查 Origin 在 WithOrigins 中
↓
返回 Access-Control-Allow-Origin: http://localhost:3001
↓
浏览器允许前端接收响应 ✓
复杂请求流程(POST/PUT/DELETE + 自定义头)
前端 (3001)
↓
发起 POST 请求
↓
浏览器自动发送 OPTIONS 预检请求
├─ Origin: http://localhost:3001
├─ Access-Control-Request-Method: POST
└─ Access-Control-Request-Headers: content-type
↓
后端 (2011) CORS 中间件处理
├─ 检查 Origin 在白名单中 ✓
├─ 检查方法被允许 ✓
├─ 检查头被允许 ✓
↓
返回预检响应
├─ Access-Control-Allow-Origin: http://localhost:3001
├─ Access-Control-Allow-Methods: POST, PUT, DELETE, ...
├─ Access-Control-Allow-Headers: content-type, ...
└─ Access-Control-Allow-Credentials: true
↓
浏览器预检通过 ✓
↓
浏览器发送真实 POST 请求
↓
后端处理并返回数据 ✓
↓
前端接收数据 ✓
🔧 API 端点验证
测试后端连接
# 基本连接测试
curl -I http://localhost:2011
# 预期响应: HTTP 200
# API 文档
curl http://localhost:2011/antis.doc
测试 CORS 预检请求
curl -X OPTIONS http://localhost:2011/api/some-endpoint \
-H "Origin: http://localhost:3001" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: content-type" \
-v
预期响应头:
Access-Control-Allow-Origin: http://localhost:3001
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Credentials: true
前端 API 调用示例
// axios 配置
import axios from 'axios'
const request = axios.create({
baseURL: 'http://localhost:2011',
timeout: 10000,
withCredentials: true // 允许跨域凭据
})
// 请求拦截器
request.interceptors.request.use(
config => {
config.headers['Authorization'] = `Bearer ${token}`
return config
}
)
// 调用 API
request.get('/api/some-endpoint')
.then(res => console.log(res))
.catch(err => console.error(err))
⚠️ 常见 CORS 错误排查
错误 1:Access to XMLHttpRequest blocked by CORS policy
原因: Origin 不在白名单中
解决方案:
// 在 appsettings.json 中添加
"WithOrigins": [
"http://localhost:3001" // ← 确保包含您的前端地址
]
错误 2:The value of the 'Access-Control-Allow-Credentials' header
原因: AllowCredentials 为 true,但 AllowAnyOrigin 被设置
解决方案:
// 不能同时设置
builder.AllowAnyOrigin().AllowCredentials(); // ❌ 错误
// 应该明确指定来源
builder.WithOrigins("http://localhost:3001").AllowCredentials(); // ✅ 正确
错误 3:Response header 'access-token' is not allowed
原因: 响应头未在白名单中
解决方案:
"WithExposedHeaders": [
"access-token",
"x-access-token",
"Content-Disposition"
]
📊 CORS 配置清单
- [x] CORS 中间件在 ConfigureServices 中注册
- [x] CORS 中间件在 Configure 中应用
- [x] 前端源 (http://localhost:3001) 在白名单中
- [x] 允许 OPTIONS 请求
- [x] 允许所有 HTTP 方法
- [x] 允许自定义请求头
- [x] 暴露必要的响应头
- [x] 允许认证凭据 (Credentials)
- [x] 预检请求正确处理
🔐 安全建议
生产环境配置
{
"CorsAccessorSettings": {
"PolicyName": "ProductionCors",
"WithOrigins": [
"https://yourdomain.com", // 只允许生产环境域名
"https://admin.yourdomain.com"
],
"AllowCredentials": true,
"SetPreflightMaxAge": 3600
}
}
JWT 令牌管理
{
"JWTSettings": {
"ValidateIssuerSigningKey": true,
"IssuerSigningKey": "your-secure-key",
"ValidateIssuer": true,
"ValidIssuer": "your-issuer",
"ValidateAudience": true,
"ValidAudience": "your-audience",
"ValidateLifetime": true,
"ExpiredTime": 1440,
"ClockSkew": 5
}
}
📞 故障诊断
步骤 1: 检查服务状态
# 检查后端
curl -I http://localhost:2011
# 期望: HTTP 200
# 检查前端
curl -I http://localhost:3001
# 期望: HTTP 200
步骤 2: 查看浏览器控制台
- 打开 F12 开发者工具
- 切换到 Network 标签
- 刷新页面
- 查找 OPTIONS 请求(预检请求)
- 检查 Response Headers:
Access-Control-Allow-OriginAccess-Control-Allow-MethodsAccess-Control-Allow-Headers
步骤 3: 查看后端日志
# netcore 会在控制台输出
# 【时间】...
# 【等级】...
# 【消息】...
# 查找与 CORS 相关的错误
步骤 4: 使用 curl 测试
# 模拟前端发送的预检请求
curl -X OPTIONS http://localhost:2011/api/endpoint \
-H "Origin: http://localhost:3001" \
-H "Access-Control-Request-Method: POST" \
-v
# 检查响应头中是否包含 Access-Control-* 字段
🎯 总结
✅ 配置文件: netcore/src/Application/NCC.API/appsettings.json
✅ 中间件文件: netcore/src/Application/NCC.API.Core/Startup.cs
✅ CORS 策略: NCCCorsAccessor
✅ 前端源: http://localhost:3001 ✓ (已在白名单中)
✅ API 端口: 2011
✅ 跨域状态: 已配置 ✓
最后更新: 2025-01-01
维护者: ERP 开发团队