1.概述
在任何现代浏览器中,随着通过REST API的数据访问模式,跨源资源共享(CORS)是与HTML5和JS客户端的出现相关的规范。
在许多情况下,为JS提供服务的主机(例如example.com)与提供数据的主机(例如api.example.com)不同。在这种情况下,CORS启用跨域通信。
Spring 为CORS提供了一流的支持,在任何Spring或Spring Boot Web应用程序中提供了一种简单而强大的配置方法。
2.控制器方法CORS配置
启用CORS非常简单 - 只需添加注释@CrossOrigin即可。
我们可以通过多种不同的方式实现这一点。
2.1。@CrossOrigin在RequestMapping-Annotated 注释的处理程序方法上
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
在上面的示例中,CORS仅对retrieve()方法启用。我们可以看到我们没有为@CrossOrigin注释设置任何配置,因此默认配置发生:
- 所有来源都是允许的
- 允许的HTTP方法是@RequestMapping注释中指定的方法(对于此示例是GET)
- 高速缓存预检响应的时间(maxAge)为30分钟
2.2。控制器上的@CrossOrigin
@CrossOrigin(origins = "http://example.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
由于@CrossOrigin被添加到Controller,因此retrieve()和remove()方法都启用了它。:我们可以通过指定注释的一个属性的值自定义配置origins
,methods
,allowedHeaders
,exposedHeaders
,allowCredentials
或maxAge
。
2.3。*****@CrossOrigin在****控制器和处理程序方法*
@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin("http://example.com")
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
Spring将结合两个注释的属性来创建合并的CORS配置。
在此示例中,两个方法的maxAge均为3600秒,方法remove()将允许所有origins,但方法retrieve()将仅允许来自http://example.com的origins。
3.全局CORS配置
作为细粒度基于注释的配置的替代方案,Spring允许我们从控制器中定义一些全局CORS配置。这类似于使用基于Filter的解决方案,但可以在Spring MVC中声明,并与细粒度的@CrossOrigin配置相结合。
默认情况下,允许所有原点和GET,HEAD和POST方法。
3.1。JavaConfig
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
上面的示例启用从任何源到应用程序中任何端点的CORS请求。
如果我们想要将其更多地锁定,则registry.addMapping方法返回CorsRegistration对象,该对象可用于其他配置。还有一个allowedOrigins方法,您可以使用它来指定允许的原点数组。如果需要在运行时从外部源加载此数组,这可能很有用。
此外,而allowedMethods,allowedHeaders,exposedHeaders,maxAge和allowCredentials,它们可用于设置响应标头并为我们提供更多自定义选项。
3.2。XML命名空间
这种最小的XML配置使/ / **路径模式上的CORS 具有与JavaConfig相同的默认属性:
<mvc:cors>
<mvc:mapping path="/**" />
</mvc:cors>
也可以使用自定义属性声明多个CORS映射:
<mvc:cors>
<mvc:mapping path="/api/**"
allowed-origins="http://domain1.com, http://domain2.com"
allowed-methods="GET, PUT"
allowed-headers="header1, header2, header3"
exposed-headers="header1, header2" allow-credentials="false"
max-age="123" />
<mvc:mapping path="/resources/**"
allowed-origins="http://domain1.com" />
</mvc:cors>
4.它是如何工作的
CORS请求会自动分派到已注册的各种HandlerMappings。它们通过CorsProcessor 实现(默认为DefaultCorsProcessor)处理CORS预检请求并拦截CORS简单和实际请求,以便添加相关的CORS响应头(例如Access-Control-Allow-Origin)。
CorsConfiguration 允许指定如何处理CORS请求:允许的来源,标题和方法等。这可以通过各种方式提供:
- 是AbstractHandlerMapping#setCorsConfiguration()允许指定一个Map与几个CorsConfiguration映射到路径图形S诸如* / API / ***
- 子类可以通过覆盖AbstractHandlerMapping#getCorsConfiguration(Object,HttpServletRequest)方法来提供自己的CorsConfiguration
- 处理程序可以实现CorsConfigurationSource 接口(就像ResourceHttpRequestHandler现在一样),以便为每个请求提供CorsConfiguration
5.结论
在本文中,我们展示了Spring如何在我们的应用程序中为启用CORS提供支持。
我们从控制器的配置开始。我们看到我们只需要添加注释@CrossOrigin,以便为一个特定方法或整个控制器启用CORS。
最后,我们还看到,如果我们想要控制控制器之外的CORS配置,我们可以在配置文件中轻松执行 - 使用JavaConfig或XML。
GitHub上提供了这些示例的完整源代码。