NOTE: Someone else originally asked this question but deleted it before I could post my answer. Since this question covers many issues that developers face when trying to make SignalR work cross-domain, I decided to replicate it. Plus, I had already finished writing the answer!
I'm running a SignalR 1.0.1 server in an ASP.NET MVC .NET Framework 4 project. I have another ASP.NET application on a different domain (different localhost port) trying to connect via the JavaScript client. I get this when my application tries to connect:
XMLHttpRequest cannot load http://localhost:31865/api/negotiate?_=1363105027533.
Origin http://localhost:64296 is not allowed by Access-Control-Allow-Origin.
I've followed all steps to enable cross-domain support with SignalR -- what am I missing?
jQuery.support.cors = true;
$.connection('http://localhost:31865/api', '', false, { jsonp: true, xdomain: true });
RouteTable.Routes.MapHubs(new HubConfiguration { EnableCrossDomain = true });
RouteTable.Routes.MapConnection<ApiConnection>("/api", "api");
I also added the following to Web.config in the API project:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
I'm using a PersistentConnection for my SignalR server, not hubs.
Any ideas?
MapHubs
will configure an endpoint at /signalr for communicating with all yourHub
classes. Since you are not using Hubs, the call toMapHubs
is unnecessary. The call toMapHubs
also does not have any effect on the configuration of your /api connection.Your call to MapConnection should be changed to read as follows:
NOTE: The second argument to
MapConnection
is the URL. The first argument is the route name. The/
is unnecessary, but doesn't really hurt in either case.Setting
jQuery.support.cors = true;
should ONLY be done "To enable cross-domain requests in environments that do not support cors yet but do allow cross-domain XHR requests (windows gadget, etc)"[1]
. This does not pertain to any versions of IE or any other browser that I know of. If the browser does not support CORS, SignalR will already automatically fall back to JSONP unless you setjQuery.support.cors
to true.If you just set this to true blindly, SignalR will assume that the environment does support cross-domain XHR requests and not automatically fall back to JSONP rendering SignalR unable to establish cross-domain connections while running in browsers that truly don't support CORS.
$.connection('http://localhost:31865/api', '', false, { jsonp: true, xdomain: true });
is incorrect. You should only needxdomain
is no longer an option for the SignalR JS client, and if you really want to specifyjsonp
, you should do it when youstart
the connection like so:I should reiterate that SignalR will automatically fall back to JSONP if the environment does not support CORS, so you should not specify this option yourself. JSONP does not require an
Access-Control-Allow-Origin
header, but it does force SignalR to use its most inefficient transport: long polling.You do not need to setup
customHeaders
in your Web.config. SignalR will set theAccess-Control-Allow-Origin
header in SignalR responses automatically when you setEnableCrossDomain
to true in youConnectionConfiguration
.Reference https://github.com/SignalR/SignalR/wiki/QuickStart-Persistent-Connections for more advice abut using
PersistentConnections
.