EDIT: This is apparently only a problem in Chrome, it works fine in FF and IE
Chrome version: 27.0.1453.116
I've got a simple JS/HTML site on localhost:13371, and I'm trying to access a SignalR hub at localhost:13371.
Whenever the request is made, I get the following error:
XMLHttpRequest cannot load
http://localhost:13370/signalr/hubs/negotiate?_=1372338722032
. Originhttp://localhost:13371
is not allowed by Access-Control-Allow-Origin.
Enabling Cross-Domain on SignalR on Application_Start
:
RouteTable.Routes.MapHubs(new HubConfiguration { EnableCrossDomain = true });
Enabling Cross-Domain in the Web.Config of the SignalR server:
<system.webServer>
<httpProtocol>
<customHeaders>
<clear />
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="*" />
<add name="Access-Control-Allow-Headers" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
Setting up the connection url on signalr's hub in JavaScript:
$.connection.hub.url = 'http://localhost:13370/signalr/hubs';
Enabling CORS in jQuery:
$.support.cors = true;
Setting response header manually in Application_BeginRequest
:
protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
//These headers are handling the "pre-flight" OPTIONS call sent by the browser
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "*");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
}
Additional information:
As I found in this Stack Overflow question, basically nearly everything I had added in my listing of "things I've tried" above were unnecessary. Steps to fix:
Remove everything I've listed that I've tried above. That means no custom headers specified at all in the Web.Config or elsewhere like the Global.asax, no custom jquery settings, etc.
.. except for RouteTable.Routes.MapHubs(new HubConfiguration { EnableCrossDomain = true });
In the Application_Start
.
Also you still need to set the $.connection.hub.url = 'http://localhost:13370/signalr/hubs';
... that's it. this is probably the best solution and the one I ended up using.
If you're still having problems like this in Chrome you can use jsonp to get that negotiate script to download properly... adding the following to my JavaScript hub start solved the issue:
//detect chrome
var isChrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
//set the connection url.
$.connection.hub.url = 'http://localhost:13370/signalr/hubs';
//use jsonp if chrome
$.connection.hub.start({
jsonp: isChrome
});
There is probably a better way to do this that tests the browser capabilities and sets jsonp accordingly... looking at the user agent feels dirty as hell... but this solved my problem in the interim. I hope this helps someone else.
This worked for me. Put this method on Global.asax.cs
protected void Application_BeginRequest(object sender, EventArgs e)
{
Context.Response.AppendHeader("Access-Control-Allow-Credentials", "true");
var referrer = Request.UrlReferrer;
if (Context.Request.Path.Contains("signalr/") && referrer != null)
{
Context.Response.AppendHeader("Access-Control-Allow-Origin", referrer.Scheme + "://" + referrer.Authority);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With