cors 不适用于我的 Spring Boot 应用程序

Posted

技术标签:

【中文标题】cors 不适用于我的 Spring Boot 应用程序【英文标题】:cors not working for my spring boot application 【发布时间】:2017-01-31 10:01:57 【问题描述】:

这是我的网络配置

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter 

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

我有一个/health 端点,它返回一些健康数据并且工作正常。

这里是junit测试

@Test
    public void corsTest() 
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.ORIGIN, "http://localhost:9000");
        HttpEntity<?> requestEntity = new HttpEntity(headers);
        ResponseEntity<Status> entity = this.restTemplate.exchange("/health", HttpMethod.GET, requestEntity, Status.class);
        assertEquals(HttpStatus.OK, entity.getStatusCode());
        assertEquals("http://localhost:9000", entity.getHeaders().getAccessControlAllowOrigin()); //6
        Status health = entity.getBody();
        assertThat(health.getAppName()).isEqualTo(appName);
    

测试在第 6 行失败。如果注释掉该行,则测试通过。 通过调试器,我发现entity.getHeaders().getAccessControlAllowOrigin() 为空。我使用这个sample app 作为参考,它工作正常。但对于我的应用程序它失败了。

当我使用 javascript 调用 /health api 时,我可以看到 cors 工作。如果我注释掉 webConfig 类,我会在 javascript 中得到错误。在 javascript 上调试更多显示未设置 cors 响应标头,但启用 webconfig 时请求成功服务。

所以绝对 cors 有效。失败的是测试。所以我猜由于我不知道的原因,测试没有看到它。

【问题讨论】:

CORS 只适用于 AJAX 请求,所以写一个模拟 JAVA 客户端的测试很奇怪。 @zeroflagL:我也有同感。但是我上面给出的链接是用java编写的。所以我试图模仿它 【参考方案1】:

我认为您需要添加 cors origin 过滤器,我不确定,但我认为以下解决方案适合您。

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCORSFilter implements Filter 

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException 

        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Headers", "Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization");
        if(request.getMethod().equals(HttpMethod.OPTIONS.name()))
            response.setStatus(HttpStatus.NO_CONTENT.value());
        else
            chain.doFilter(req, res);
        
    

    public void init(FilterConfig filterConfig) 

    public void destroy() 

【讨论】:

【参考方案2】:

正如我所解释的here,需要在spring boot errorPageFilter之前设置要加载的corsfilter。否则 CORS 支持将被破坏,并且不会引入所需的标头。这可以通过上面提到的@Order(Ordered.HIGHEST_PRECEDENCE) 来完成。

【讨论】:

我没有使用过滤器 您的解决方案对我来说很好。但是,我不明白为什么。我认为这是 CorsFilter 的错误或缺点。 不确定我是否理解...只是订单注释不起作用?【参考方案3】:

我假设你没有使用注解驱动的 cors 配置,而是 java 配置。

在这种情况下,我发现您发布的示例与来自 github 的示例有所不同。

后一种使用

registry.addMapping("/greeting-javaconfig").allowedOrigins("http://localhost:9000");

而您的示例错过了 allowedOrigins

registry.addMapping("/greeting-javaconfig");

我认为这在这里有所不同。

【讨论】:

我允许来源 *.这就是为什么它缺少它

以上是关于cors 不适用于我的 Spring Boot 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot JWT Cors 不适用于 Angular 8

Spring Boot CORS 过滤器不适用于 AngularJS

Spring Security Logout 不适用于 Spring 4 CORS

@CrossOrigin 不适用于 spring-boot-starter-web 2.5.2

Spring - CORS 不适用于安全配置

Spring Boot + Thymeleaf css 不适用于模板