Angular 7'Access-Control-Allow-Origin'标头包含多个值

lia*_* xu 8 spring-mvc angular angular7

我在端口4202中提供了角度应用程序,并通过以下代码连接到remove spring mvc应用程序。

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

但是它报告了以下错误。

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.
Run Code Online (Sandbox Code Playgroud)

因此,我尝试通过控制器方法下的注释在我的spring Web应用程序中启用cors。

@CrossOrigin(origins = "http://localhost:4202")
Run Code Online (Sandbox Code Playgroud)

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

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}
Run Code Online (Sandbox Code Playgroud)

然后刷新下面的前端用户界面。

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.
Run Code Online (Sandbox Code Playgroud)

然后我检查了我的Chrome网络,如下所示,它确实复制了“ Access-control-allow-origin”头。 在此处输入图片说明

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

然后,我尝试通过提琴手而不是有角度的人直接访问此url(http:// localhost:8080 / api / hero / list)。下面是屏幕截图,我发现没有重复的“ Access-Control-Allow-Origin”。 在此处输入图片说明

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

小智 1

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

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