问题
I am trying to implement a simple notification system using SignalR for my server, and Angular for my client. When I run my angular application after starting my server, I receive this error:
Failed to load http://localhost:1874/notify/negotiate: Response to
preflight request doesn't pass access control check: The value of the 'Access-
Control-Allow-Credentials' header in the response is '' which must be 'true'
when the request's credentials mode is 'include'. Origin 'http://localhost:4200'
is therefore not allowed access. The credentials mode of
requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
I believe this may have something to do with cors? My server is just sending notifications and my client is displaying them. That is it. Right at the start up, my application is unable to connect to the server. Here is my startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace SignalRHub
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
{
builder
.AllowAnyMethod()
.AllowAnyHeader()
.WithOrigins("http://localhost:4200");
}));
services.AddSignalR();
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors("CorsPolicy");
app.UseSignalR(routes =>
{
routes.MapHub<NotifyHub>("/notify");
});
app.UseMvc();
}
}
}
And here is my Angular Component class:
import { Component, OnInit } from '@angular/core';
import { HubConnection, HubConnectionBuilder } from '@aspnet/signalr';
import { Message } from 'primeng/api';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
private _hubConnection: HubConnection;
msgs: Message[] = [];
constructor() { }
ngOnInit(): void {
this._hubConnection = new HubConnectionBuilder().withUrl('http://localhost:1874/notify').build();
this._hubConnection
.start()
.then(() => console.log('Connection started!'))
.catch(err => console.log('Error while establishing connection :('));
this._hubConnection.on('BroadcastMessage', (type: string, payload: string) => {
this.msgs.push({ severity: type, summary: payload });
});
}
}
Here is the github where I am following the tutorial from.
https://github.com/rukshandangalla/Angular5-SignalR-Notifications
Thank you.
回答1:
You will also need to allow credentials.
To do so, change ConfigureServices, and add .AllowCredentials() like so:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
{
builder
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.WithOrigins("http://localhost:4200");
}));
services.AddSignalR();
services.AddMvc();
}
来源:https://stackoverflow.com/questions/52081412/signalr-angular-failed-to-loadurl-response-to-preflight-request-doesnt-pass