跨源资源共享(CORS)是一种机制,允许许多安全的跨源请求,比如Ajax。在本文中,我们将首先介绍CORS的基本原理,然后会详细讨论在Spring框架中配置CORS的几种方法。
1. CORS的基本原理
当你试图从一个不同的源(域名、协议或端口)执行XMLHttpRequest或Fetch时,浏览器会实现同源策略来阻止这种行为。CORS就是一种让服务器告诉浏览器应该放宽同源策略的机制。
在CORS机制中,浏览器会在跨源HTTP请求上发送额外的 "CORS headers",其中一些是在请求中,一些是在响应中。这些头信息告诉浏览器应该如何处理跨源请求和响应。
2. 在Spring框架中配置CORS
在Spring框架中,有多种方式可以配置支持跨域请求。以下是几种常见的方法:
2.1 在过滤器中添加CORS头信息
你可以创建一个自定义的Servlet过滤器来处理跨域请求。这个过滤器会检查请求的源(即 ORIGIN 头),并根据这个源是否在白名单中,决定是否在响应头添加CORS相关的信息。
在下面的示例中,doFilter 方法会检查 ORIGIN 是否在白名单中,如果在的话,就向响应头添加CORS相关的头信息,包括 Access-Control-Allow-Origin、Access-Control-Allow-Methods、Access-Control-Max-Age、Access-Control-Allow-Headers 和 Access-Control-Allow-Credentials。
response.setHeader("Access-Control-Allow-Origin", safeOrigin);
response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Authorization,content-type,token");
response.setHeader("Access-Control-Allow-Credentials", "true");
2.2 使用@CrossOrigin注解
在Spring MVC的控制器或处理程序方法上使用@CrossOrigin注解,可以为特定的HTTP请求处理程序启用CORS。例如:
@RestController
public class MyController {
@CrossOrigin(origins = "http://example.com")
@RequestMapping("/")
public String index() {
return "Greetings from Spring Boot!";
}
}
在这个例子中,只有来自http://example.com的请求才会被接受。
2.3 全局CORS配置
你可以在Spring MVC中使用Java配置来定义全局CORS配置。这可以通过重写addCorsMappings(CorsRegistry registry)方法来完成。例如:
@Configuration
public class MyConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://example.com")
.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD")
.allowCredentials(true)
.maxAge(3600);
}
}
在这个例子中,所有的URL路径都允许来自http://example.com的跨域请求。
2.4 使用Spring Boot的CorsFilter
如果你正在使用Spring Boot,你可以直接在配置文件中定义CORS映射,然后通过CorsFilter来应用这些映射。例如:
@Configuration
public class MyConfiguration {
@Bean
public FilterRegistrationBean<CorsFilter> corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://example.com");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}
}
在这个例子中,所有的URL路径都允许来自http://example.com的跨域请求。