出现错误:“Access-Control-Allow-Origin”标头包含多个值“*、*”,但只允许一个

Posted

技术标签:

【中文标题】出现错误:“Access-Control-Allow-Origin”标头包含多个值“*、*”,但只允许一个【英文标题】:Getting error: 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed 【发布时间】:2021-06-21 12:05:08 【问题描述】:

我试图在我的 Angular 前端和 Java / Spring 中的 REST 端点之间建立连接(我没有开发,也不太了解)。通过 GET,一切正常。通过 POST,我在终端收到消息

已被 CORS 政策阻止:对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。

并且,在开发工具的“网络”选项卡中,OPTIONS 方法出现错误 403

Request Method: OPTIONS
Status Code: 403 
Remote Address: xx.xx.xx.xx:xxxx
Referrer Policy: strict-origin-when-cross-origin

所以,我在互联网上多次搜索后发现了这种情况,原因是 CORS 设置:通常,在这种情况下,OPTIONS 调用在 POST 之前发送;但是,由于 CORS,不允许调用 OPTIONS。所以,我试图在我的控制器上设置这一行

@CrossOrigin(origins = "*", methods = RequestMethod.OPTIONS, RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE)

这次错误发生了变化

Multiple CORS header 'Access-Control-Allow-Origin' not allowed
But the code I added is the only similar to @CrossOrigin, I dind't found others similar.

所以,根据CORS issue - No 'Access-Control-Allow-Origin' header is present on the requested resource的帖子,我尝试了以下解决方案:

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter 

    @Override
    public void addCorsMappings(CorsRegistry registry) 
        registry.addMapping("/**")
                .allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
    

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter 
    @Override
    protected void configure(HttpSecurity http) throws Exception 
//        http.csrf().disable();
        http.cors();
    

    @Bean
    public CorsConfigurationSource corsConfigurationSource() 
        final CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(ImmutableList.of("*"));
        configuration.setAllowedMethods(ImmutableList.of("HEAD",
                "GET", "POST", "PUT", "DELETE", "PATCH"));
        // setAllowCredentials(true) is important, otherwise:
        // The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
        configuration.setAllowCredentials(true);
        // setAllowedHeaders is important! Without it, OPTIONS preflight request
        // will fail with 403 Invalid CORS request
        configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type"));
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    

但是这次我在控制台看到的错误变成了

已被 CORS 策略阻止:“Access-Control-Allow-Origin”标头包含多个值“*、*”,但只允许一个。

所以,这是我到达的最后一点。如何解决关于多个值的最后一个错误?每次我处理这个问题时,我都会提前一步,错误会发生变化,但它仍然存在。

【问题讨论】:

您能否将带有标题的请求添加到您的问题中。 origin 标头的值是多少?还添加带有标题的响应?回复中有多少Access-Control-Allow-Origin 您可以尝试删除@CrossOrigin(origins = "*", methods = RequestMethod.OPTIONS, RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE) 看起来你有两个不同的过滤器,添加 Access-Control-Allow-Origin 标题。 【参考方案1】:

只需将其添加到您的 WebSecurityConfigurerAdapter

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 

    
/*@Override
    public void addCorsMappings(CorsRegistry registry) 
        registry.addMapping("/**")
                .allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
    */ not needed

@Override
    protected void configure(HttpSecurity http) throws Exception 
        http
            // by default uses a Bean by the name of corsConfigurationSource
            .cors(withDefaults())
            ...
    

    @Bean
    CorsConfigurationSource corsConfigurationSource() 
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("https://localhost:5000"));// if your front end running on localhost:5000
        configuration.setAllowedMethods(Arrays.asList("GET","POST"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    

确保除了上面的代码之外,您没有任何其他过滤器或 cors 注释

Spring CORS section 在 Spring Security 文档中。

如果你没有使用 Spring Security:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@SpringBootApplication
public class DemoApplication 

    public static void main(String[] args) 
        SpringApplication.run(DemoApplication.class, args);
    


    @Bean
    public WebMvcConfigurer corsConfigurer() 
        return new WebMvcConfigurer() 
            @Override
            public void addCorsMappings(CorsRegistry registry) 
                registry
                .addMapping("/**")
                .allowedOrigins("*","http://localhost:5000");// list all domains
            
        ;
    

【讨论】:

我建议不要在 allowedOrigins 中使用*。而是使用您的 Angular 应用程序的域。以http://localhost:5000 为例 抱歉,我不明白,1) 我应该删除哪些其他设置 2) 我应该在哪里添加提到的行?你可以通过编辑你的原始回复来回复我,所以比这个 cmets 更清楚吗?这么多建议,但我不知道我应该在哪里申请。感谢您的宝贵时间。 我完全按照你写的做了,但我看到了同样的错误。我还尝试删除 allowOrigin 行,并且我看到了有关允许来源错误的另一个错误。为什么?谢谢 让我们continue this discussion in chat.

以上是关于出现错误:“Access-Control-Allow-Origin”标头包含多个值“*、*”,但只允许一个的主要内容,如果未能解决你的问题,请参考以下文章

SPRING BOOT跨域访问处理

PHP Ajax 跨域问题最佳解决方案

PHP Ajax 跨域问题最佳解决方案

PHP Ajax 跨域问题最佳解决方案

跨域问题实践总结! 上(JSONP/document.domain/window.name)

nginx跨域(网上找的)