springBoot CORS跨域注解@CrossOrigin

1、概述

在任何现代浏览器中,随着 HTML5 和 JS 客户端的出现,跨域资源共享 (CORS)是一项相关规范,这些客户端通过 REST API 使用数据。

通常,服务于 JS 的主机(例如 example.com)与服务于数据的主机(例如 api.example.com)是不同的。在这种情况下,CORS 可以实现跨域通信。

Spring 为 CORS 提供一流的支持,为在任何 Spring 或 Spring Boot Web 应用程序中配置它提供了一种简单而强大的方式。

2.控制器方法CORS配置

启用 CORS 很简单——只需添加注释@CrossOrigin

我们可以通过几种不同的方式实现这一点。

2.1。@CrossOrigin@RequestMapping-带注释的处理程序方法上

@RestController
@RequestMapping("/account")
public class AccountController {

    @CrossOrigin
    @RequestMapping(method = RequestMethod.GET, path = "/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

在上面的示例中,我们只为retrieve()方法启用了 CORS 。我们可以看到我们没有为@CrossOrigin注解设置任何配置,所以它使用默认值:

  • 允许所有来源。
  • 允许的 HTTP 方法是在@RequestMapping注释中指定的方法(本例中为 GET)。
  • 预检响应的缓存时间 ( maxAge ) 为 30 分钟。

2.2. 控制器上的@CrossOrigin

@CrossOrigin(origins = "http://example.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

    @RequestMapping(method = RequestMethod.GET, path = "/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

这一次,我们在类级别添加了@CrossOrigin。因此,retrieve()remove()方法都启用了它。我们可以通过指定注释属性之一的值来自定义配置:originsmethodsallowedHeadersexposedHeadersallowCredentialsmaxAge

2.3. @CrossOrigin关于控制器和处理程序方法

@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

    @CrossOrigin("http://example.com")
    @RequestMapping(method = RequestMethod.GET, "/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

Spring 将结合来自两个注解的属性来创建一个合并的 CORS 配置。

在这里,两个方法的maxAge都是 3,600 秒,remove()方法将允许所有来源,retrieve()方法只允许来自http://example.com的来源。

3. 全局 CORS 配置

作为细粒度的基于注释的配置的替代方案,Spring 允许我们在控制器之外定义一些全局 CORS 配置。这类似于使用基于Filter的解决方案,但可以在 Spring MVC 中声明并结合细粒度的@CrossOrigin配置。

默认情况下,允许所有来源和 GET、HEAD 和 POST 方法。

3.1。Java配置

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}

上面的示例启用了从任何来源到应用程序中任何端点的 CORS 请求。

为了进一步锁定这一点,registry.addMapping方法返回一个CorsRegistration对象,我们可以将其用于其他配置。还有一个allowedOrigins方法可以让我们指定一个允许来源的数组。如果我们需要在运行时从外部源加载此数组,这将很有用。

此外,还有allowedMethodsallowedHeadersexposedHeadersmaxAge 和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. 带有 Spring Security 的 CORS

如果我们在项目中使用 Spring Security,我们必须采取额外的步骤来确保它与 CORS 兼容。那是因为需要先处理 CORS。否则,Spring Security 将在请求到达 Spring MVC 之前拒绝该请求。

幸运的是,Spring Security 提供了一个开箱即用的解决方案:

@EnableWebSecurity
	public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	    @Override
	    protected void configure(HttpSecurity http) throws Exception {
	        http.cors().and()...
	    }
	}

这篇文章更详细地解释了它。

5. 它是如何工作的

CORS 请求会自动分派到各种已注册的HandlerMappings。它们处理 CORS 预检请求并使用CorsProcessor 实现(默认为DefaultCorsProcessor)拦截 CORS 简单和实际请求,以添加相关的 CORS 响应标头(例如Access-Control-Allow-Origin)。

CorsConfiguration允许我们指定应该如何处理 CORS 请求,包括允许的来源、标头和方法等。我们可以通过多种方式提供:

  • AbstractHandlerMapping#setCorsConfiguration()允许我们指定一个Map,其中几个CorsConfiguration映射到路径模式,例如/api/**
  • 子类可以通过覆盖AbstractHandlerMapping#getCorsConfiguration(Object, HttpServletRequest)方法来提供自己的CorsConfiguration 。
  • 处理程序可以实现CorsConfigurationSource 接口(就像现在的ResourceHttpRequestHandler一样)为每个请求提供CorsConfiguration

6. 结论

在本文中,我们展示了 Spring 如何为在我们的应用程序中启用 CORS 提供支持。

我们从控制器的配置开始。我们看到我们只需要添加注解@CrossOrigin来启用 CORS 到一个特定的方法或整个控制器。

此外,我们了解到,为了在控制器之外控制 CORS 配置,我们可以使用 JavaConfig 或 XML 在配置文件中顺利执行此操作。

示例的完整源代码可在 GitHub 上获得。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 不完全正确。@CrossOrigin注解可以解决本地跨域问题,但在某些情况下可能会遇到一些限制。引用中的报错信息指出,当设置allowCredentials为true时,allowedOrigins不能包含特殊值"*",因为在"Access-Control-Allow-Origin"响应头中不能设置"*"。解决方案是明确列出允许使用credentials的origins,或者考虑使用"allowedOriginPatterns"代替。此外,引用提到除了细粒度、基于注释的配置之外,可能还需要定义一些全局CORS配置。这些配置可以在Spring MVC中声明,并结合细粒度的@CrossOrigin配置。默认情况下,所有origins和GET、HEAD和POST方法都是被允许的。因此,@CrossOrigin可以解决本地跨域问题,但在一些特殊情况下可能需要额外的配置。举个例子,可以在控制器类上使用@CrossOrigin注解来允许跨域访问,并在请求方法上使用@RequestMapping注解来定义具体的请求路径和方法类型。例如: ```java @CrossOrigin @RestController public class PersonController { @RequestMapping(method = RequestMethod.GET) public String add() { // 执行相关操作 } } ```<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [解决springboot添加@CrossOrigin支持跨域不起作用](https://blog.csdn.net/qq_45721173/article/details/124634565)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [注解@CrossOrigin解决跨域问题](https://blog.csdn.net/qq_39176597/article/details/112982244)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值