对预检请求的响应未通过访问控制检查:响应中“Access-Control-Allow-Credentials”标头的值为“”

Posted

技术标签:

【中文标题】对预检请求的响应未通过访问控制检查:响应中“Access-Control-Allow-Credentials”标头的值为“”【英文标题】:Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' 【发布时间】:2019-01-05 06:42:00 【问题描述】:

我正在使用 Angular 6 和 asp.net 核心上的 SignalR 功能。但是不断收到此错误对预检请求的响应未通过访问控制检查:响应中“Access-Control-Allow-Credentials”标头的值是“”,当请求的凭据时必须为“真”模式是“包含”。

做了一些研究,发现是服务器端的CORS问题。所以修改了服务器代码。

startup.cs

public void ConfigureServices(IServiceCollection services)
        
    services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
                
                    builder.AllowAnyOrigin()
                           .AllowAnyMethod()
                           .AllowAnyHeader()
                           .WithOrigins("http://localhost:4200");
                ));
     services.AddSignalR();


public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        
         app.UseCors("CorsPolicy");
         app.UseSignalR(routes =>
            
                routes.MapHub<SignalR>("/rule");
            );

角度应用

ngOnInit() 
this.callSignalR()


    private callSignalR(): void 
        // set up the signal R
        let connection = new signalR.HubConnectionBuilder().withUrl(environment.baseUrl+"/rule").build();
        //start the connection 
        connection.start().then(() => connection.invoke("updateRules", this.autheService.getCurrentuser.userId));
        //Get the response from the server
        connection.on("updateRules", data => console.log(data);); 
      

参考资料

Access-Control-Allow-Origin - Angular 5

'Access-Control-Allow-Credentials' header in the response is '' which must be 'true'

https://github.com/aspnet/SignalR/issues/2095

https://github.com/SignalR/SignalR/issues/1694

https://github.com/aspnet/SignalR/issues/2110

【问题讨论】:

【参考方案1】:

您必须允许您的 cors-policy 凭据,因为 signalr 也在传递 cookie。

public void ConfigureServices(IServiceCollection services)
        
    services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
                
                    builder.AllowAnyOrigin()
                           .AllowAnyMethod()
                           .AllowAnyHeader()
                           .AllowCredentials()
                           .WithOrigins("http://localhost:4200");
                ));
     services.AddSignalR();

【讨论】:

收到另一个错误,因为无法完成与服务器的协商:错误:未找到 那么您的集线器端点无效。这是一个新错误,我建议之前为此和谷歌创建一个新问题。, 我花了半个下午试图弄清楚这一点,我需要做的就是添加 .AllowCredentials() 非常感谢【参考方案2】:

在 Startup.cs 中

public void ConfigureServices(IServiceCollection services)
    
       services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
            
                builder.AllowAnyOrigin()
                       .AllowAnyMethod()
                       .AllowAnyHeader()
                       .AllowCredentials()
                       .WithOrigins("http://localhost:4200");
            ));
       services.AddSignalR();
    


public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    
      app.UseEndpoints(endpoints => 
        
            endpoints.MapHub<BroadcastHub>("/notify");
        );

     

来自您的 Angular 应用

 ngOnInit(): void 
     const connection = new signalR.HubConnectionBuilder()
     .configureLogging(signalR.LogLevel.Information)
     .withUrl(environment.baseUrl + 'notify')
     .build();

     connection.start().then( () => 
         console.log('SignalR Connected!');
         ).catch( (err) => 
             return console.error(err.toString());
         );
      // BoradcastMessage is the name of the function in your SignalR 
      // interface.
     connection.on('BroadcastMessage', () => 
       console.log('Message from server');
     );
 

【讨论】:

以上是关于对预检请求的响应未通过访问控制检查:响应中“Access-Control-Allow-Credentials”标头的值为“”的主要内容,如果未能解决你的问题,请参考以下文章

为啥 CORS 错误“对预检请求的响应未通过访问控制检查”?

Express - 无法发送重定向,对预检请求的响应未通过访问控制检查

对预检请求的响应未通过访问控制检查

对预检请求的响应未通过访问控制检查

对预检请求的响应未通过访问控制检查

在禁用 Web 安全模式下运行的 chrome 中,对预检请求的响应未通过访问控制检查