springboot的跨域是什么?遇到跨域问题如何解决?

06-01 1187阅读

在Spring Boot中,跨域是指当浏览器中的前端应用(如运行在某个域名和端口下的前端页面)请求后端接口时,如果后端接口所在的域名、端口或协议与前端应用不一致,浏览器会阻止这种跨域请求。这是由于浏览器的同源策略(Same-Origin Policy)所导致的。

跨域产生的原因:

浏览器出于安全性考虑,会阻止不同来源(域名、端口或协议不同)之间的请求

  • 同源策略限制:浏览器出于安全考虑,实施了同源策略,即只允许页面请求同源(相同协议、域名和端口)的资源。当JavaScript发起的请求跨越了同源策略,即请求的目标与当前页面的域名、端口、协议不一致时,浏览器会阻止请求的发送或接收。

  • 前后端分离架构:在现代的前后端分离开发模式下,前端和后端通常部署在不同的服务器上,具有不同的域名或端口,这很容易导致跨域问题。

    例如:

    • 前端运行在 http://localhost:3000
    • 后端 API 在 http://localhost:8080

      当前端向 http://localhost:8080/api/data 发送请求时,浏览器会拦截并报 CORS policy 错误。

      解决跨域问题的常见方式:

      方式 1:使用 @CrossOrigin 注解(推荐小型项目或单个接口)

      在 Spring Boot 控制器(@RestController)上使用 @CrossOrigin 注解,允许跨域访问:

      1) 允许所有来源访问整个控制器
      @RestController
      @RequestMapping("/api")
      @CrossOrigin(origins = "*")  // 允许所有来源
      public class MyController {
      	@GetMapping("/data")
      	public String getData() {
      		return "Hello, CORS!";
      	}
      }
      2) 只允许特定的来源
      @CrossOrigin(origins = "http://localhost:3000") // 只允许从 http://localhost:3000 访问
      @GetMapping("/data")
      public String getData() {
          return "Hello, CORS!";
      }
      3) 细粒度控制(支持多个来源、方法、请求头)
      @CrossOrigin(origins = {"http://localhost:3000", "http://example.com"},
                   methods = {RequestMethod.GET, RequestMethod.POST},
                   allowedHeaders = {"Content-Type", "Authorization"})
      @GetMapping("/data")
      public String getData() {
          return "CORS Configured!";
      }
      

      方式 2:全局配置(推荐大型项目或所有接口都需要跨域)

      如果所有 API 都需要支持跨域,使用 CorsFilter 或 WebMvcConfigurer 进行全局配置。

      2.1) 使用 WebMvcConfigurer 配置全局 CORS,在 @Configuration 类中注册 CORS 规则:
      • 在Spring Boot应用中,可以通过创建一个配置类,实现WebMvcConfigurer接口,并重写addCorsMappings方法来全局配置跨域访问。这种方式适用于所有接口都需要跨域访问的场景。

        import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.Configuration;
        import org.springframework.web.servlet.config.annotation.CorsRegistry;
        import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
        @Configuration
        public class CorsConfig {
            
            @Bean
            public WebMvcConfigurer corsConfigurer() {
                return new WebMvcConfigurer() {
                    @Override
                    public void addCorsMappings(CorsRegistry registry) {
                        registry.addMapping("/**") // 允许所有路径
                                .allowedOrigins("http://localhost:3000") // 允许特定域访问
                                .allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的请求方法
                                .allowedHeaders("*") // 允许所有请求头
                                .allowCredentials(true); // 允许携带 Cookie
                    }
                };
            }
        }
        
        • addMapping("/**"):允许所有接口跨域
        • allowedOrigins("http://localhost:3000"):只允许 http://localhost:3000 访问
        • allowedMethods("GET", "POST", "PUT", "DELETE"):允许这些 HTTP 方法
        • allowedHeaders("*"):允许所有请求头
        • allowCredentials(true):允许携带 cookies 或 Authorization 头
          2.2) 使用 CorsFilter 配置 CORS

          另一种方式是使用 CorsFilter,这种方式也是通过Java配置的方式配置跨域访问,与全局配置CORS类似,但实现方式略有不同。

          import org.springframework.context.annotation.Bean;
          import org.springframework.context.annotation.Configuration;
          import org.springframework.web.cors.CorsConfiguration;
          import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
          import org.springframework.web.filter.CorsFilter;
          import java.util.Arrays;
          @Configuration
          public class MyCorsFilter {
              
              @Bean
              public CorsFilter corsFilter() {
                  UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
                  CorsConfiguration config = new CorsConfiguration();
                  
                  config.setAllowedOrigins(Arrays.asList("http://localhost:3000")); // 允许的前端地址
                  config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
                  config.setAllowedHeaders(Arrays.asList("*"));
                  config.setAllowCredentials(true); // 允许 Cookie
                  
                  source.registerCorsConfiguration("/**", config);
                  return new CorsFilter(source);
              }
          }
          
          • setAllowedOrigins(Arrays.asList("http://localhost:3000")):指定允许的域
          • setAllowCredentials(true):允许带 Cookies(必须与 allowedOrigins 不能设置为 "*")

            方式3. 允许携带 Cookie

            如果前端需要携带 cookie 或 Authorization 头,例如 fetch 或 Axios 发送请求时 credentials: 'include',你需要:

            1. 在后端 allowCredentials(true)
            2. 在前端请求时 credentials: 'include'

            后端

            registry.addMapping("/**")
                    .allowedOrigins("http://localhost:3000")
                    .allowedMethods("GET", "POST")
                    .allowCredentials(true);  // 允许携带 Cookie
            

            前端(使用 Fetch)

            fetch('http://localhost:8080/api/data', {
                method: 'GET',
                credentials: 'include' // 允许携带 Cookie
            })
            .then(response => response.json())
            .then(data => console.log(data))
            .catch(error => console.error(error));
            

            前端(使用 Axios)

            springboot的跨域是什么?遇到跨域问题如何解决?
            (图片来源网络,侵删)
            axios.get('http://localhost:8080/api/data', { withCredentials: true })
              .then(response => console.log(response.data))
              .catch(error => console.error(error));
            

            方式4. 通过Nginx配置CORS

            如果项目中使用了Nginx作为反向代理服务器,也可以在Nginx中配置CORS来解决跨域问题。

            server {
                ...
                location / {
                    add_header 'Access-Control-Allow-Origin' '*';
                    add_header 'Access-Control-Allow-Headers' '*';
                    add_header 'Access-Control-Allow-Methods' '*';
                    if ($request_method = 'OPTIONS') {
                        return 204;
                    }
                }
                ...
            }

            通过以上方法,可以在Spring Boot应用中有效地解决跨域问题,确保前后端之间的正常通信。

            springboot的跨域是什么?遇到跨域问题如何解决?
            (图片来源网络,侵删)

            常见 CORS 错误及解决方法

            错误信息可能原因解决方案
            Access to fetch at 'http://localhost:8080' from origin 'http://localhost:3000' has been blocked by CORS policy后端未配置 CORS配置 @CrossOrigin 或 WebMvcConfigurer
            Response to preflight request doesn’t pass access control checkOPTIONS 请求被拦截在后端允许 OPTIONS 方法
            Missing Allow-Control-Allow-Origin headerCORS 头未返回确保后端 allowedOrigins 设置正确
            credentials mode is 'include' but Access-Control-Allow-Credentials is missing需要携带 Cookie 但未允许在后端 allowCredentials(true)

            总结

            方法适用场景配置方式
            @CrossOrigin适用于单个接口在 @RestController 或方法级别使用
            WebMvcConfigurer适用于整个项目CorsRegistry 配置
            CorsFilter高级定制使用 CorsConfiguration

            在 Spring Boot 项目中,推荐使用 WebMvcConfigurer 进行全局跨域配置,@CrossOrigin 适用于局部控制。

            springboot的跨域是什么?遇到跨域问题如何解决?
            (图片来源网络,侵删)
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码