【问题标题】:Angular 7 The 'Access-Control-Allow-Origin' header contains multiple valuesAngular 7“Access-Control-Allow-Origin”标头包含多个值
【发布时间】:2019-04-05 11:17:45
【问题描述】:

我在端口 4202 中为 angular 应用程序提供服务,并通过以下代码连接到删除 spring mvc 应用程序。

this.http.post<Hero[]>('http://localhost:8080/api/hero/list', {"id":1}, httpOptions)

但它报告了以下错误。

Failed to load http://localhost:8080/api/hero/list: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4202' is therefore not allowed access. The response had HTTP status code 403.

所以我尝试通过控制器方法中的以下注释在我的 Spring Web 应用程序中启用 cors。

@CrossOrigin(origins = "http://localhost:4202")

我还尝试添加如下配置类。

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

然后我刷新我的前端 ui,如下所示。

Failed to load http://localhost:8080/api/hero/list: The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost:4202, *', but only one is allowed. Origin 'http://localhost:4202' is therefore not allowed access.

然后我检查了我的 chrome 网络,如下所示,它确实重复了“Access-control-allow-origin”头。

然后我用谷歌搜索了很多,发现其他人遇到了这个问题,因为 Tomcat 前面的其他 Web 服务器生成了第二个“Access-control-allow-origin”头。但是我只有一个tomcat服务器,除了'ng serve'启动的服务器。

然后我尝试通过 fiddler 而不是 angular 直接访问这个 url(http://localhost:8080/api/hero/list)。下面是截图,我可以发现没有重复的“Access-Control-Allow-Origin”。

所以我猜测是不是由angular启动的nodejs服务器引起的?由于我是 Angular 的新手,我不知道如何看待这个问题。谢谢。

【问题讨论】:

  • 由于您在 Angular HttpClient 中使用 localhost:8080/api... 进行调用,因此不要通过本地 Angular CLI 开发服务器。你直接进入你的 Spring 端点。所以它一定是服务器端的问题。作为旁注,我通常不执行 CORS 请求,而是在我的 Angular CLI 开发服务器上使用代理配置,以避免在后端执行 CORS。我有一篇关于它的文章,如何设置它:juristr.com/blog/2016/11/configure-proxy-api-angular-cli

标签: angular spring-mvc angular7


【解决方案1】:

Angular 与您的 Java 应用程序服务器在不同的来源上工作,这就是需要 CORS 的原因。 我不是 Spring 专家,但据我了解您的问题会发生以下情况: 当您执行 POST 请求时,服务器会自行添加允许来源标头。它可能会读取 Endpoints 方法规范以添加所需的允许方法标头(至少在 Java EE 中)并设置 allow origin * 标头(我强烈反对生产,最好设置预期的允许域)。由于您的 Controller 注释,设置了一个额外的标题。这是无效的,因为CORS specification 只允许一个具有一个值的 cors 原始标头。通过将您的应用服务器配置为设置无并通过一些注释来处理此问题,或让应用服务器处理此问题或由负载平衡器设置此标头(如果您使用一个),确保仅设置一个。 第二件事(实际上是您得到的初始错误)是预检请求。如果您执行的请求可能会更改服务器状态(例如发布请求),则 cors 要求您首先回答 OPTIONS 请求(以便浏览器可以在您发送修改请求之前检查 cors)。此选项请求必须具有 200ish 响应代码,并提供 cors allow headers for origin 和 methods(包括您的案例中的 post)。

对于本地开发,您还可以使用this one 之类的代理。这不会强迫您在本地处理 cors 并修改您的后端。

【讨论】:

    【解决方案2】:

    您要在后端代码中添加两个标头,只需删除 @CrossOrigin(origins = "http://localhost:4202") 并仅保留 WebConfig 配置,因为您允许该配置中的所有来源。

    【讨论】:

      【解决方案3】:

      我也有同样的问题。在我的情况下,我的后端服务器基于微服务架构(spring webflux)并且所有微服务都在更新跨源头,因此它有多个值,然后我通过将 cors 配置仅移动到网关来修复它,将其从所有其他微服务。这解决了我的问题!

      【讨论】:

        【解决方案4】:

        您在微服务和网关上都配置了跨源过滤器配置。 仅将配置保留在 api 网关中,如下所示,

        @SpringBootApplication
        @EnableEurekaClient
        @EnableZuulProxy
        public class ZuulApiGatewayApplication {
        
            public static void main(String[] args) {
                SpringApplication.run(ZuulApiGatewayApplication.class, args);
            }
        
        
        
            @Bean
            public CorsFilter corsFilter() {
                final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
                final CorsConfiguration config = new CorsConfiguration();
                config.setAllowCredentials(true);
                config.addAllowedOrigin("*");
                config.addAllowedHeader("*");
                config.addAllowedMethod("GET");
                config.addAllowedMethod("POST");
                config.addAllowedMethod("DELETE");
                config.addAllowedMethod("PUT");
                config.setMaxAge(18000L);
                source.registerCorsConfiguration("/**", config);
                return new CorsFilter(source);
            }
        

        【讨论】:

          猜你喜欢
          • 2017-11-10
          • 2016-10-02
          • 2020-02-04
          • 2019-01-08
          • 2023-03-24
          • 2018-01-06
          • 1970-01-01
          • 2019-04-09
          相关资源
          最近更新 更多