简体   繁体   中英

Self Hosting SignalR and Access Control Allow Origin

I'm trying to achieve the following: 1. Server (WinForms for now) that hosts a SignalR persistent connection 2. ASP.NET MVC client

The server runs on port 8000 and the client runs (via Visual Studio) on port 22914. But when I test this, I get the following error:

XMLHttpRequest cannot load http://localhost:8000/echo/negotiate?_=1352825948654. Origin http://localhost:22914 is not allowed by Access-Control-Allow-Origin.

So far so good, I need to specify that Cross Domain communication is allowed. I assume this needs to be done on the server. But where and how? I can't find a solution and unfortunately, there aren't a lot of resources on the web about self hosting a SignalR connection in a WinForms app.

Well there's two ways that CORS can work: simple requests and pre-flight requests.

Simple requests just make the normal request with the GET / POST verbs and expect to find the Access-Control-Allow-Origin header in the normal response. In a pre-flight scenario an OPTION request is send out and you need to handle that verb specifically and respond with a bunch of Access-Control-XXX headers.

Without going fully into the spec to support this you would need to get in the middle of response in your host and inject the Access-Control-Allow-Origin header for simple requests. You would also need to add specific handling for the OPTION verb if you expect clients that might use the pre-flight approach. Since I don't know exactly how you're doing your custom hosting I can't give you specific advice on how to do that, but hopefully this sets you on your way.

I recently encountered this problem myself; the answer is to specify the Server Url and Port in your Client application, ie for the following scenario:

Server: http://localhost:8000/

Client: http://localhost:22914/

Client Application:

$.connection.hub.url = 'http://localhost:8000/signalr'

$.connection.hub.start();

Documented at the bottom of the SignalR Client Hubs Wiki on Github

In looking at the SignalR code, it looks as if the self-hosted server automatically adds in the Access-Control-Allow-Origin when it's responding, by simply reflecting back the "Origin" value in the request headers.

From Microsoft.AspNet.SignalR.Hosting.Self.Server.ProcessRequestAsync() :

string origin = context.Request.Headers["Origin"];
if (!String.IsNullOrEmpty(origin))
{
    context.Response.AddHeader("Access-Control-Allow-Origin", origin);
    context.Response.AddHeader("Access-Control-Allow-Credentials", "true");
}

Apparently the assumption is that if you're self-hosting, everything is going to be cross-domain, so let's go ahead and allow everything. I'm not sure if that's the best assumption, but it certainly makes one less thing to get wrong when wiring things up.

Also, it doesn't necessarily address your problem - but it does mean that the issue probably doesn't have to do with not having the Access-Control-Allow-Origin set in the header.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM