Springboot怎么解决跨域请求问题

发布时间:2023-05-17 16:28:26 作者:zzz
来源:亿速云 阅读:163

Springboot怎么解决跨域请求问题

在现代Web开发中,跨域请求(Cross-Origin Resource Sharing, CORS)是一个常见的问题。跨域请求指的是浏览器从一个域名下的网页向另一个域名下的服务器发起请求。由于浏览器的同源策略(Same-Origin Policy),这种请求通常会被阻止,除非服务器明确允许。

Spring Boot 提供了多种方式来解决跨域请求问题。本文将介绍几种常见的解决方案。

1. 使用 @CrossOrigin 注解

@CrossOrigin 注解是 Spring Boot 中最简单的解决跨域问题的方式。你可以将这个注解添加到控制器类或方法上,以允许特定的跨域请求。

示例代码

@RestController
@RequestMapping("/api")
public class MyController {

    @CrossOrigin(origins = "http://example.com")
    @GetMapping("/data")
    public String getData() {
        return "Hello, CORS!";
    }
}

在这个例子中,@CrossOrigin 注解允许来自 http://example.com 的跨域请求访问 /api/data 端点。

参数说明

2. 全局配置 CORS

如果你希望在整个应用程序中启用跨域请求,可以使用全局配置的方式。Spring Boot 提供了 WebMvcConfigurer 接口来实现全局 CORS 配置。

示例代码

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOrigins("http://example.com")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

在这个例子中,addCorsMappings 方法配置了所有 /api/** 路径的跨域请求,允许来自 http://example.com 的请求,并允许 GET, POST, PUT, DELETE 方法。

3. 使用 CorsFilter 过滤器

如果你需要更细粒度的控制,可以使用 CorsFilter 过滤器。这种方式允许你在请求处理链的早期阶段处理跨域请求。

示例代码

@Bean
public CorsFilter corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("http://example.com");
    config.addAllowedHeader("*");
    config.addAllowedMethod("*");
    source.registerCorsConfiguration("/api/**", config);
    return new CorsFilter(source);
}

在这个例子中,CorsFilter 过滤器配置了所有 /api/** 路径的跨域请求,允许来自 http://example.com 的请求,并允许所有 HTTP 方法和请求头。

4. 使用 @CrossOrigin 注解与全局配置结合

在某些情况下,你可能希望同时使用 @CrossOrigin 注解和全局配置。Spring Boot 允许你这样做,但需要注意优先级问题。@CrossOrigin 注解的配置会覆盖全局配置。

示例代码

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOrigins("http://example.com")
                .allowedMethods("GET", "POST");
    }
}

@RestController
@RequestMapping("/api")
public class MyController {

    @CrossOrigin(origins = "http://another-example.com")
    @GetMapping("/data")
    public String getData() {
        return "Hello, CORS!";
    }
}

在这个例子中,全局配置允许来自 http://example.com 的请求访问 /api/** 路径,但 @CrossOrigin 注解允许来自 http://another-example.com 的请求访问 /api/data 路径。

5. 处理预检请求(Preflight Request)

跨域请求中的预检请求(Preflight Request)是浏览器在发送实际请求之前发送的一个 OPTIONS 请求,用于检查服务器是否允许跨域请求。Spring Boot 会自动处理预检请求,但你也可以通过配置来控制预检请求的行为。

示例代码

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOrigins("http://example.com")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

在这个例子中,maxAge 参数设置了预检请求的缓存时间为 3600 秒,这意味着浏览器在 3600 秒内不会再次发送预检请求。

6. 使用 Spring Security 配置 CORS

如果你的应用程序使用了 Spring Security,你需要在 Spring Security 配置中启用 CORS 支持。

示例代码

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable()
            .authorizeRequests()
            .antMatchers("/api/**").permitAll()
            .anyRequest().authenticated();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowCredentials(true);
        configuration.addAllowedOrigin("http://example.com");
        configuration.addAllowedHeader("*");
        configuration.addAllowedMethod("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/api/**", configuration);
        return source;
    }
}

在这个例子中,cors() 方法启用了 CORS 支持,并通过 corsConfigurationSource 方法配置了 CORS 规则。

7. 使用 @CrossOrigin 注解与 Spring Security 结合

如果你同时使用了 @CrossOrigin 注解和 Spring Security,Spring Security 的 CORS 配置会覆盖 @CrossOrigin 注解的配置。

示例代码

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable()
            .authorizeRequests()
            .antMatchers("/api/**").permitAll()
            .anyRequest().authenticated();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowCredentials(true);
        configuration.addAllowedOrigin("http://example.com");
        configuration.addAllowedHeader("*");
        configuration.addAllowedMethod("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/api/**", configuration);
        return source;
    }
}

@RestController
@RequestMapping("/api")
public class MyController {

    @CrossOrigin(origins = "http://another-example.com")
    @GetMapping("/data")
    public String getData() {
        return "Hello, CORS!";
    }
}

在这个例子中,Spring Security 的 CORS 配置允许来自 http://example.com 的请求访问 /api/** 路径,但 @CrossOrigin 注解允许来自 http://another-example.com 的请求访问 /api/data 路径。由于 Spring Security 的配置优先级更高,@CrossOrigin 注解的配置将被忽略。

8. 使用 CorsConfigurationSource Bean

如果你需要更复杂的 CORS 配置,可以使用 CorsConfigurationSource Bean。这种方式允许你在不同的路径上应用不同的 CORS 配置。

示例代码

@Configuration
public class CorsConfig {

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config1 = new CorsConfiguration();
        config1.setAllowCredentials(true);
        config1.addAllowedOrigin("http://example.com");
        config1.addAllowedHeader("*");
        config1.addAllowedMethod("*");

        CorsConfiguration config2 = new CorsConfiguration();
        config2.setAllowCredentials(true);
        config2.addAllowedOrigin("http://another-example.com");
        config2.addAllowedHeader("*");
        config2.addAllowedMethod("*");

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/api/v1/**", config1);
        source.registerCorsConfiguration("/api/v2/**", config2);

        return source;
    }
}

在这个例子中,CorsConfigurationSource Bean 配置了两个不同的 CORS 规则,分别应用于 /api/v1/**/api/v2/** 路径。

9. 使用 @CrossOrigin 注解与 CorsConfigurationSource Bean 结合

如果你同时使用了 @CrossOrigin 注解和 CorsConfigurationSource Bean,CorsConfigurationSource Bean 的配置会覆盖 @CrossOrigin 注解的配置。

示例代码

@Configuration
public class CorsConfig {

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://example.com");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/api/**", config);

        return source;
    }
}

@RestController
@RequestMapping("/api")
public class MyController {

    @CrossOrigin(origins = "http://another-example.com")
    @GetMapping("/data")
    public String getData() {
        return "Hello, CORS!";
    }
}

在这个例子中,CorsConfigurationSource Bean 配置了所有 /api/** 路径的跨域请求,允许来自 http://example.com 的请求,但 @CrossOrigin 注解允许来自 http://another-example.com 的请求访问 /api/data 路径。由于 CorsConfigurationSource Bean 的配置优先级更高,@CrossOrigin 注解的配置将被忽略。

10. 使用 CorsFilter 过滤器与 CorsConfigurationSource Bean 结合

如果你同时使用了 CorsFilter 过滤器和 CorsConfigurationSource Bean,CorsFilter 过滤器的配置会覆盖 CorsConfigurationSource Bean 的配置。

示例代码

@Configuration
public class CorsConfig {

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://example.com");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/api/**", config);

        return source;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://another-example.com");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/api/**", config);
        return new CorsFilter(source);
    }
}

在这个例子中,CorsConfigurationSource Bean 配置了所有 /api/** 路径的跨域请求,允许来自 http://example.com 的请求,但 CorsFilter 过滤器配置了所有 /api/** 路径的跨域请求,允许来自 http://another-example.com 的请求。由于 CorsFilter 过滤器的配置优先级更高,CorsConfigurationSource Bean 的配置将被忽略。

11. 使用 @CrossOrigin 注解与 CorsFilter 过滤器结合

如果你同时使用了 @CrossOrigin 注解和 CorsFilter 过滤器,CorsFilter 过滤器的配置会覆盖 @CrossOrigin 注解的配置。

示例代码

@Configuration
public class CorsConfig {

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://example.com");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/api/**", config);
        return new CorsFilter(source);
    }
}

@RestController
@RequestMapping("/api")
public class MyController {

    @CrossOrigin(origins = "http://another-example.com")
    @GetMapping("/data")
    public String getData() {
        return "Hello, CORS!";
    }
}

在这个例子中,CorsFilter 过滤器配置了所有 /api/** 路径的跨域请求,允许来自 http://example.com 的请求,但 @CrossOrigin 注解允许来自 http://another-example.com 的请求访问 /api/data 路径。由于 CorsFilter 过滤器的配置优先级更高,@CrossOrigin 注解的配置将被忽略。

12. 使用 @CrossOrigin 注解与 CorsConfigurationSource Bean 和 CorsFilter 过滤器结合

如果你同时使用了 @CrossOrigin 注解、CorsConfigurationSource Bean 和 CorsFilter 过滤器,CorsFilter 过滤器的配置会覆盖 CorsConfigurationSource Bean 和 @CrossOrigin 注解的配置。

示例代码

@Configuration
public class CorsConfig {

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://example.com");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/api/**", config);

        return source;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://another-example.com");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/api/**", config);
        return new CorsFilter(source);
    }
}

@RestController
@RequestMapping("/api")
public class MyController {

    @CrossOrigin(origins = "http://yet-another-example.com")
    @GetMapping("/data")
    public String getData() {
        return "Hello, CORS!";
    }
}

在这个例子中,CorsConfigurationSource Bean 配置了所有 /api/** 路径的跨域请求,允许来自 http://example.com 的请求,CorsFilter 过滤器配置了所有 /api/** 路径的跨域请求,允许来自 http://another-example.com 的请求,但 @CrossOrigin 注解允许来自 http://yet-another-example.com 的请求访问 /api/data 路径。由于 CorsFilter 过滤器的配置优先级更高,CorsConfigurationSource Bean 和 @CrossOrigin 注解的配置将被忽略。

13. 使用 @CrossOrigin 注解与 CorsConfigurationSource Bean 和 CorsFilter 过滤器结合

如果你同时使用了 @CrossOrigin 注解、CorsConfigurationSource Bean 和 CorsFilter 过滤器,CorsFilter 过滤器的配置会覆盖 CorsConfigurationSource Bean 和 @CrossOrigin 注解的配置。

示例代码

@Configuration
public class CorsConfig {

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://example.com");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/api/**", config);

        return source;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://another-example.com");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/api/**", config);
        return new CorsFilter(source);
    }
}

@RestController
@RequestMapping("/api")
public class MyController {

    @CrossOrigin(origins = "http://yet-another-example.com")
    @GetMapping("/data")
    public String getData() {
        return "Hello, CORS!";
    }
}

在这个例子中,CorsConfigurationSource Bean 配置了所有 /api/** 路径的跨域请求,允许来自 http://example.com 的请求,CorsFilter 过滤器配置了所有 /api/** 路径的跨域请求,允许来自 http://another-example.com 的请求,但 @CrossOrigin 注解允许来自 http://yet-another-example.com 的请求访问 /api/data 路径。由于 CorsFilter 过滤器的配置优先级更高,CorsConfigurationSource Bean 和 @CrossOrigin 注解的配置将被忽略。

14. 使用 @CrossOrigin 注解与 CorsConfigurationSource Bean 和 CorsFilter 过滤器结合

如果你同时使用了 @CrossOrigin 注解、CorsConfigurationSource Bean 和 CorsFilter 过滤器,`Cors

推荐阅读:
  1. SpringBoot怎么调用外部接口实现数据交互
  2. Java SpringBoot分布式事务问题如何解决

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

springboot

上一篇:SpringBoot如何使用WebSocket实现点对点消息

下一篇:SpringBoot如何集成SFTP客户端实现文件上传下载

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》