CORS 策略已阻止对 XMLHttpRequest 的访问:Spring API 和 Angular UI

Posted

技术标签:

【中文标题】CORS 策略已阻止对 XMLHttpRequest 的访问:Spring API 和 Angular UI【英文标题】:Access to XMLHttpRequest has been blocked by CORS policy : Spring API and Angular UI 【发布时间】:2021-03-13 02:39:21 【问题描述】:

我正在尝试从托管在 localhost:4200 的节点服务器中的 Angular UI 应用程序访问在 localhost:9090 的 tomcat 服务器上运行的 REST API。

这是我遇到的错误,无法访问服务

在浏览器控制台中看到的默认错误

从源“http://localhost:4200”访问“http://localhost:9090/rest/authentication/login”处的 XMLHttpRequest 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:它没有 HTTP ok 状态。

在Chrome中添加CORS插件并在浏览器中关闭CORS后,这是错误

从源“http://localhost:4200”访问“http://localhost:9090/rest/authentication/login”处的 XMLHttpRequest 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:“Access-Control-Allow-Origin”标头包含多个值“http://localhost:4200, *”,但只允许一个。

REST 服务是使用 Spring 5.0 构建的,我们尝试通过在 web.xml 中添加以下内容来处理跨源

<filter>
  <filter-name>CORS</filter-name>
       <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
             <init-param>
                    <param-name>cors.allowed.origins</param-name>
                    <param-value>http://localhost:4200</param-value>
             </init-param>
             <init-param>
                    <param-name>cors.allowed.methods</param-name>
                    <param-value>GET,POST,PUT,DELETE,HEAD,OPTIONS</param-value>
             </init-param>
             <init-param>
                    <param-name>cors.allowed.headers</param-name>
                    <param-value>Content-Type,X-Requested-With,Accept,Authorization,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
             </init-param>
             <init-param>
                    <param-name>cors.exposed.headers</param-name>
                    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
             </init-param>
       </filter>

</filter>

克服此 CORS 错误的任何解决方案

【问题讨论】:

【参考方案1】:

为您的控制器或其方法添加 @CrossOrigin("http://localhost:4200") 注释或全局启用 CORS:

@Bean
public CorsFilter corsFilter() 
    final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    final CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    // Don't do this in production, use a proper list  of allowed origins
    config.setAllowedOrigins(Collections.singletonList("*"));
    config.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept"));
    config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH"));
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);

编辑

如果是 Spring Security 问题,请将其添加到您的 SecurityConfig:

@Bean
    public CorsConfigurationSource corsConfigurationSource() 
        final CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
        configuration.setAllowCredentials(true);
        configuration.setAllowedHeaders(Arrays.asList("*"));
        configuration.setExposedHeaders(Arrays.asList("x-auth-token", "xsrf-token", "Access-Control-Allow-Origin"));
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    

【讨论】:

我们在控制器级别尝试了@crossOrigin。但这不起作用,因为甚至在到达控制器类之前就抛出了错误。您能否详细说明如何在全球范围内启用 CORS。是否通过添加扩展 javax.servlet.Filter 的自定义过滤器类并添加您的 cmets 中显示的逻辑。 应用不是Spring Boot,是普通的Spring框架。此外,我们还有一个自定义过滤器类实现,我们在其中验证登录用户。我们在这一层收到的请求是 Options 类型的,而不是从 UI 发出的实际 GET/POST 请求。 @chinnuNish 我能想到的唯一原因是 Spring Security 阻止它(请注意,您确实将 Options 方法添加到过滤器)。我添加了一个编辑

以上是关于CORS 策略已阻止对 XMLHttpRequest 的访问:Spring API 和 Angular UI的主要内容,如果未能解决你的问题,请参考以下文章

AngularJs——对 XMLHttpRequest 的访问已被 CORS 策略阻止 [重复]

CORS 策略已阻止从源对 X 的 XMLHttpRequest 的 CORS 访问

套接字 IO 错误“对 XMLHttpRequest 的访问已被 CORS 策略阻止”

CORS 策略已阻止从源“localhost”访问“localhost”处的 XMLHttpRequest:对预检的响应 [关闭]

来源已被 CORS 策略阻止 对预检请求的响应未通过访问控制检查

CORS 策略已阻止对 XMLHttpRequest 的访问:Spring API 和 Angular UI