您好,登录后才能下订单哦!
在现代Web开发中,跨域请求(Cross-Origin Resource Sharing, CORS)是一个常见的问题。跨域请求指的是浏览器从一个域名下的网页向另一个域名下的服务器发起请求。由于浏览器的同源策略(Same-Origin Policy),这种请求通常会被阻止,除非服务器明确允许。
Spring Boot 提供了多种方式来解决跨域请求问题。本文将介绍几种常见的解决方案。
@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 端点。
origins: 允许的源列表,默认为 *(允许所有源)。methods: 允许的 HTTP 方法列表,默认为 GET, POST, HEAD。allowedHeaders: 允许的请求头列表,默认为 *(允许所有头)。exposedHeaders: 允许暴露给客户端的响应头列表。allowCredentials: 是否允许发送凭据(如 cookies),默认为 false。maxAge: 预检请求的缓存时间(秒),默认为 1800 秒。如果你希望在整个应用程序中启用跨域请求,可以使用全局配置的方式。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 方法。
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 方法和请求头。
@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 路径。
跨域请求中的预检请求(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 秒内不会再次发送预检请求。
如果你的应用程序使用了 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 规则。
@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 注解的配置将被忽略。
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/** 路径。
@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 注解的配置将被忽略。
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 的配置将被忽略。
@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 注解的配置将被忽略。
@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 注解的配置将被忽略。
@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 注解的配置将被忽略。
@CrossOrigin 注解与 CorsConfigurationSource Bean 和 CorsFilter 过滤器结合如果你同时使用了 @CrossOrigin 注解、CorsConfigurationSource Bean 和 CorsFilter 过滤器,`Cors
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。