1. 跨域问题前端开发的拦路虎第一次遇到跨域问题时我盯着浏览器控制台那个鲜红的Access-Control-Allow-Origin错误提示整整发呆了十分钟。当时正在开发一个前后端分离的项目前端运行在http://localhost:3000后端API在http://localhost:8080明明两个服务都在本地浏览器却死活不让前端获取后端数据。后来才知道这正是跨域问题的典型表现——即使域名相同端口不同也会触发浏览器的同源策略限制。同源策略就像小区的门禁系统要求访问者和被访问者必须满足三个同一同一协议http/https、同一域名包括子域名、同一端口号。这个安全机制虽然保护了用户数据却给开发者带来了不少麻烦。常见的跨域场景包括开发环境前端开发服务器与后端API地址不同微服务架构不同服务部署在不同子域名下第三方API集成需要调用其他公司的接口CDN资源静态资源托管在不同域名2. CORS跨域通信的通行证2.1 CORS工作原理剖析CORS机制就像海关的出入境检查通过HTTP头部信息完成问询-应答流程。当浏览器发现跨域请求时会自动进入CORS流程简单请求直接发送请求但会在请求头添加Origin字段GET /api/data HTTP/1.1 Origin: http://localhost:3000服务器响应需要包含Access-Control-Allow-Origin: http://localhost:3000预检请求针对复杂请求先发OPTIONS请求探路OPTIONS /api/data HTTP/1.1 Origin: http://localhost:3000 Access-Control-Request-Method: PUT服务器需要响应允许的方法和头信息Access-Control-Allow-Origin: http://localhost:3000 Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: Content-Type2.2 Spring Boot中的CORS配置实战在Spring Boot项目中我通常根据场景选择三种配置方式方法级注解适合特定接口RestController RequestMapping(/api) public class UserController { CrossOrigin(origins http://localhost:3000) GetMapping(/users) public ListUser getUsers() { // ... } }控制器级注解适用于整个模块CrossOrigin(origins {http://localhost:3000, https://prod-site.com}, maxAge 3600) RestController RequestMapping(/api) public class ProductController { // 所有方法都继承CORS配置 }全局配置推荐生产环境使用Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOrigins(http://localhost:3000, https://your-domain.com) .allowedMethods(GET, POST, PUT, DELETE) .allowedHeaders(*) .allowCredentials(true) .maxAge(3600); } }注意当allowCredentials为true时allowedOrigins不能使用通配符*必须明确指定域名3. Nginx反向代理跨域问题的终极解法3.1 Nginx解决跨域的核心原理Nginx就像个中间人让浏览器以为所有请求都来自同一个源。假设前端https://example.com后端APIhttps://api.internal.com通过Nginx配置可以让浏览器访问https://example.com/api/xxx而Nginx在背后悄悄把请求转发到真实的后端地址。这样从浏览器角度看所有请求都在同源下完成。3.2 生产级Nginx配置详解这是我经过多个项目验证的优化配置模板server { listen 443 ssl; server_name example.com; # SSL配置 ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; # 前端静态资源 location / { root /var/www/frontend; index index.html; try_files $uri $uri/ /index.html; } # API代理设置 location /api/ { proxy_pass https://api.internal.com/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # CORS头设置 add_header Access-Control-Allow-Origin https://example.com always; add_header Access-Control-Allow-Methods GET, POST, PUT, DELETE, OPTIONS always; add_header Access-Control-Allow-Headers DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization always; add_header Access-Control-Expose-Headers Content-Length,Content-Range always; # 处理预检请求 if ($request_method OPTIONS) { add_header Access-Control-Max-Age 1728000; add_header Content-Type text/plain; charsetutf-8; add_header Content-Length 0; return 204; } } # 其他静态资源 location /static/ { alias /var/www/static/; expires 1y; access_log off; } }3.3 常见坑点与解决方案问题1配置了Nginx但依然跨域检查proxy_pass地址结尾是否带/影响URI转发确认add_header指令放在正确的位置有些指令不能在某些上下文中使用问题2Cookie无法跨域确保withCredentials设置为true前端检查Nginx配置中的Access-Control-Allow-Credentials头确认Access-Control-Allow-Origin不是通配符*问题3预检请求失败确保OPTIONS方法被允许检查Access-Control-Allow-Headers是否包含所有需要的头4. 高级场景与性能优化4.1 微服务架构下的跨域方案在微服务环境中我推荐采用API网关统一处理跨域。以Spring Cloud Gateway为例spring: cloud: gateway: globalcors: cors-configurations: [/**]: allowedOrigins: https://example.com allowedMethods: * allowedHeaders: * allowCredentials: true maxAge: 36004.2 缓存优化策略频繁的预检请求会影响性能可以通过以下方式优化设置较长的maxAge如3600秒对静态资源使用单独的跨域策略尽可能使用简单请求避免触发预检4.3 安全加固建议生产环境避免使用通配符*定期审查allowedOrigins列表对敏感接口添加额外的认证头启用HTTPS并配置HSTS在实际项目中我通常会根据项目阶段选择不同方案开发环境用Spring Boot的CrossOrigin快速验证测试环境用Nginx模拟生产配置生产环境则采用网关精细化控制的组合方案。记得有次在紧急上线时因为Nginx配置少了个斜杠导致整个API不可用这个教训让我养成了部署前必做三项检查的习惯配置文件语法检查、跨域测试用例验证、以及生产环境灰度发布。