lee.2m 2025-09-23 12:55 采纳率: 98.3%
浏览 0
已采纳

Spring Boot与Vue接口跨域问题如何解决?

在前后端分离架构中,使用Spring Boot作为后端、Vue作为前端时,常因浏览器同源策略导致接口跨域问题。典型表现为:Vue项目运行在 `http://localhost:8080`,而Spring Boot服务部署在 `http://localhost:8081`,发起请求时浏览器报错“Access-Control-Allow-Origin”拒绝访问。该问题虽不影响服务本身通信,但阻碍开发调试与正常交互,需通过合理配置CORS(跨域资源共享)解决。
  • 写回答

1条回答 默认 最新

  • 冯宣 2025-09-23 12:55
    关注

    前后端分离架构中的跨域问题深度解析与实战解决方案

    1. 什么是同源策略与CORS机制?

    浏览器的同源策略(Same-Origin Policy)是Web安全的核心机制之一,它限制了一个源(协议 + 域名 + 端口)的文档或脚本如何与另一个源的资源进行交互。当Vue前端运行在http://localhost:8080,而Spring Boot后端服务部署在http://localhost:8081时,两者端口不同,即视为非同源,因此浏览器会阻止XMLHttpRequest或Fetch请求。

    CORS(Cross-Origin Resource Sharing)是一种W3C标准,通过在HTTP响应头中添加特定字段(如Access-Control-Allow-Origin),允许服务器声明哪些外部源可以访问其资源,从而实现安全的跨域通信。

    2. 跨域请求的典型表现与错误分析

    开发者在调试过程中常遇到如下浏览器控制台报错:

    
            Access to fetch at 'http://localhost:8081/api/user' 
            from origin 'http://localhost:8080' 
            has been blocked by CORS policy: 
            No 'Access-Control-Allow-Origin' header is present on the requested resource.
        

    该错误表明:尽管后端服务正常响应,但未设置正确的CORS响应头,导致浏览器主动拦截响应数据。值得注意的是,这类问题仅出现在浏览器环境,使用Postman或curl等工具调用接口通常不受影响。

    3. Spring Boot中配置CORS的五种方式

    以下是按复杂度递增排列的五种主流CORS配置方案:

    1. @CrossOrigin注解:适用于单个Controller或方法级别。
    2. 全局CORS配置类:通过实现WebMvcConfigurer统一管理。
    3. 过滤器(Filter)方式:灵活控制请求/响应头。
    4. Spring Security集成CORS:在安全框架下正确处理预检请求。
    5. <5>反向代理(Nginx):生产环境推荐方案,彻底规避前端跨域。

    4. 方案一:@CrossOrigin注解(开发阶段快速验证)

    在Controller类或具体方法上添加注解,开启跨域支持:

    
    @RestController
    @CrossOrigin(origins = "http://localhost:8080")
    public class UserController {
    
        @GetMapping("/api/user")
        public ResponseEntity<User> getUser() {
            return ResponseEntity.ok(new User("John Doe"));
        }
    }
        

    优点:简单直接;缺点:粒度粗、难以维护多源策略。

    5. 方案二:全局CORS配置(推荐开发/测试环境)

    创建配置类,集中管理所有跨域规则:

    
    @Configuration
    @EnableWebMvc
    public class CorsConfig implements WebMvcConfigurer {
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/api/**")
                    .allowedOrigins("http://localhost:8080")
                    .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                    .allowedHeaders("*")
                    .allowCredentials(true)
                    .maxAge(3600);
        }
    }
        

    此方式可统一控制路径匹配、请求方法、凭证传递等参数,适合中大型项目。

    6. 方案三:自定义Filter实现细粒度控制

    对于需要动态判断来源或日志审计的场景,可编写过滤器:

    
    @Component
    public class CustomCorsFilter implements Filter {
    
        @Override
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
                throws IOException, ServletException {
            HttpServletResponse response = (HttpServletResponse) res;
            HttpServletRequest request = (HttpServletRequest) req;
    
            response.setHeader("Access-Control-Allow-Origin", "http://localhost:8080");
            response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "*");
            response.setHeader("Access-Control-Allow-Credentials", "true");
    
            if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
                response.setStatus(HttpServletResponse.SC_OK);
            } else {
                chain.doFilter(req, res);
            }
        }
    }
        

    7. 方案四:Spring Security中的CORS集成

    若项目启用Spring Security,需确保CORS配置优先于安全过滤链:

    
    @Configuration
    @EnableWebSecurity
    public class SecurityConfig {
    
        @Bean
        public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
            http.cors().and()
                .csrf().disable()
                .authorizeRequests().anyRequest().permitAll();
            return http.build();
        }
    
        @Bean
        public CorsConfigurationSource corsConfigurationSource() {
            CorsConfiguration config = new CorsConfiguration();
            config.setAllowedOriginPatterns(Arrays.asList("http://localhost:8080"));
            config.setAllowedMethods(Arrays.asList("*"));
            config.setAllowCredentials(true);
            config.setAllowedHeaders(Arrays.asList("*"));
    
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            source.registerCorsConfiguration("/api/**", config);
            return source;
        }
    }
        

    8. 方案五:Nginx反向代理(生产环境最佳实践)

    通过Nginx将前后端统一在同一域名下,从根本上消除跨域问题:

    前端请求Nginx代理目标实际后端地址
    /root /usr/share/nginx/html;Vue静态资源
    /api/proxy_pass http://localhost:8081;Spring Boot服务

    9. 预检请求(Preflight Request)与OPTIONS方法处理

    当请求包含自定义头、认证信息或非简单方法时,浏览器会先发送OPTIONS预检请求。Spring Boot默认不处理OPTIONS,需显式放行:

    
    .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
        

    否则会导致预检失败,进而阻断主请求。

    10. 完整流程图:跨域请求生命周期

    sequenceDiagram participant Browser participant Nginx participant SpringBoot Browser->>SpringBoot: GET /api/data (CORS) alt 同源 SpringBoot-->>Browser: 直接返回数据 else 跨源 Browser->>SpringBoot: OPTIONS /api/data (Preflight) SpringBoot-->>Browser: 200 OK + CORS Headers Browser->>SpringBoot: GET /api/data SpringBoot-->>Browser: 200 OK + Data + CORS Headers end

    11. 生产环境建议与安全考量

    在生产环境中应避免使用*通配符作为Access-Control-Allow-Origin值,防止敏感接口被任意站点调用。建议采用白名单机制,并结合JWT、Referer校验等增强安全性。同时,高并发场景下应评估CORS头注入风险。

    12. Vue Axios配置与后端协同调试技巧

    前端可通过Axios设置withCredentials以支持携带Cookie:

    
    axios.defaults.baseURL = 'http://localhost:8081';
    axios.defaults.withCredentials = true;
        

    此时后端必须明确设置allowCredentials(true)allowedOrigin不能为"*"。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 10月23日
  • 创建了问题 9月23日