CORS 问题故障排查

问题1: No ‘Access-Control-Allow-Origin’ header

症状

Access to fetch at 'http://localhost:7999/api/product/list?page=1&size=10'  
from origin 'http://localhost:3000' 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,或者网关服务没有启动。

解决方案

  1. 确保网关服务已启动

    cd /Users/li/WorkSpace/year26/spring-cloud-demo-26/fake-srm/fake-gateway   mvn spring-boot:run   ```  
    
  2. 检查网关的CORS配置
    确认 fake-gateway/src/main/java/com/year26/fakegateway/config/GatewayConfig.java 中有CORS配置。

  3. 重启所有服务

    cd /Users/li/WorkSpace/year26/spring-cloud-demo-26/fake-srm   ./stop-all-services.sh  
    ./start-all-services.sh   ```
    

问题2: Access-Control-Allow-Origin header contains multiple values

症状

Access to fetch at 'http://localhost:7999/api/order/list?page=1&size=10&status=PENDING'  
from origin 'http://localhost:3000' has been blocked by CORS policy:  
The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost:3000, http://localhost:3000',  
but only one is allowed.  

原因

CORS配置被重复应用了:

  • 网关中配置了CORS
  • 微服务中也配置了CORS
  • 导致响应头中包含了重复的 Access-Control-Allow-Origin

解决方案

方式1: 一键修复(推荐)

cd /Users/li/WorkSpace/year26/spring-cloud-demo-26/fake-srm./fix-cors-issue.sh  

方式2: 手动修复

# 1. 停止所有服务  
./stop-all-services.sh  
  
# 2. 清理重复的CORS配置  
./clean-cors.sh  
  
# 3. 重新编译微服务  
cd fake-services/fake-product && mvn clean compile  
cd ../fake-order && mvn clean compile  
cd ../..  
  
# 4. 重新启动所有服务  
./start-all-services.sh  

问题3: 前端无法访问网关

症状

浏览器控制台显示网络错误,无法连接到 http://localhost:7999

原因

网关服务没有启动,或者端口被占用。

解决方案

  1. 检查网关服务状态
    curl http://localhost:7999/actuator/health   ```  
    
  2. 检查端口占用
    lsof -i :7999   ```  
    
  3. 重启网关服务
    cd /Users/li/WorkSpace/year26/spring-cloud-demo-26/fake-srm/fake-gateway   mvn spring-boot:run   ```
    

问题4: 微服务没有注册到Eureka

症状

网关无法路由到微服务,返回503错误。

原因

微服务没有启动,或者没有正确注册到Eureka。

解决方案

  1. 检查Eureka状态
    访问 http://localhost:8000/ 查看已注册的服务

  2. 检查微服务日志
    查看微服务启动日志,确认成功注册到Eureka

  3. 重启所有服务

    cd /Users/li/WorkSpace/year26/spring-cloud-demo-26/fake-srm   ./stop-all-services.sh  
    ./start-all-services.sh   ```
    

问题5: 前端显示”网络请求失败”

症状

前端页面显示错误提示:”网络请求失败,请检查网络连接”

原因

  1. 网关服务没有启动
  2. 微服务没有启动
  3. 网络连接问题

解决方案

  1. 检查所有服务状态

    curl http://localhost:7999/actuator/health   curl http://localhost:8002/actuator/health   curl http://localhost:8001/actuator/health   ```  
    
  2. 查看浏览器控制台
    打开浏览器开发者工具,查看Network标签页的详细错误信息

  3. 重启所有服务

    cd /Users/li/WorkSpace/year26/spring-cloud-demo-26/fake-srm   ./stop-all-services.sh  
    ./start-all-services.sh   ```
    

问题6: 前端显示后端错误信息

症状

前端从右侧滑入红色错误提示框,显示后端返回的错误信息,例如:

  • “订单金额超出限制(最大1999元)”
  • “产品不存在”

说明

这是正常行为!错误处理已经正确配置,前端会显示后端返回的具体错误信息。

如何验证

  1. 查看错误提示框
    错误信息会从右侧滑入显示

  2. 查看浏览器控制台
    按 F12 打开开发者工具,查看Console标签页

  3. 查看后端日志
    查看微服务的控制台输出,确认错误原因

快速诊断命令

# 1. 检查所有服务状态  
curl http://localhost:7999/actuator/health  
curl http://localhost:8002/actuator/health  
curl http://localhost:8001/actuator/health  
  
# 2. 检查Eureka注册状态  
curl http://localhost:8000/  
  
# 3. 测试API(通过网关)  
curl http://localhost:7999/api/product/list?page=1&size=10  
  
# 4. 测试API(直接访问微服务)  
curl http://localhost:8002/product/list?page=1&size=10  
  
# 5. 查看网关日志  
tail -f /tmp/gateway.log  
  
# 6. 查看微服务日志  
tail -f /tmp/fake-product.log  
tail -f /tmp/fake-order.log  

服务端口汇总

服务 端口 访问地址 说明
Eureka Server 8000 http://localhost:8000/ 服务注册中心
Gateway 7999 http://localhost:7999/api 网关(统一入口)
fake-product 8002 http://localhost:8002/product/ 产品服务
fake-order 8001 http://localhost:8001/order/ 订单服务
前端 3000 http://localhost:3000 管理界面

架构流程

浏览器 (http://localhost:3000)  ↓React 前端组件  
  ↓API 服务层 (services/api.ts)  ↓Spring Cloud Gateway (http://localhost:7999/api)  
  ↓CORS 配置(统一处理跨域)  
  ↓路由转发  
  ↓├─→ fake-product (http://localhost:8002/product/...)  
└─→ fake-order (http://localhost:8001/order/...)  
  ↓MySQL 数据库  

关键配置文件

网关CORS配置

文件: fake-gateway/src/main/java/com/year26/fakegateway/config/GatewayConfig.java

重要: 微服务中不要配置CORS,避免重复。

前端API配置

文件: fake-srm-front/services/api.ts

const API_BASE_URL = 'http://localhost:7999/api'; // fake-order 服务地址  
const PRODUCT_API_URL = 'http://localhost:7999/api'; // fake-product 服务地址  

常用脚本

# 一键启动所有服务  
./start-all-services.sh  
  
# 一键停止所有服务  
./stop-all-services.sh  
  
# 一键修复CORS问题  
./fix-cors-issue.sh  
  
# 清理重复的CORS配置  
./clean-cors.sh  

参考文档