Cross-domain will not work with a SignalR PersistentConnection

asp.net-mvc, cross-domain, javascript, signalr, signalr.client

Solution

`MapHubs` will configure an endpoint at /signalr for communicating with all your `Hub` classes. Since you are not using Hubs, the call to `MapHubs` is unnecessary. The call to `MapHubs` also does not have any effect on the configuration of your /api connection.

Your call to MapConnection should be changed to read as follows:

RouteTable.Routes.MapConnection<ApiConnection>("api", "api",
    new ConnectionConfiguration { EnableCrossDomain = true });

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 set `jQuery.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 need

var connection = $.connection('http://localhost:31865/api');

`xdomain` is no longer an option for the SignalR JS client, and if you really want to specify `jsonp`, you should do it when you `start` the connection like so:

 connection.start({ jsonp: true}).done(function () { /* ... */ });

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 the `Access-Control-Allow-Origin` header in SignalR responses automatically when you set `EnableCrossDomain` to true in you `ConnectionConfiguration`.

Reference https://github.com/SignalR/SignalR/wiki/QuickStart-Persistent-Connections for more advice abut using `PersistentConnections`.

Problem

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?

Original source