Add support for X-domain long-polling with JSONP #6

DamianEdwards opened this Issue Aug 1, 2011 · 15 comments

8 participants

SignalR member

Add support to the long-polling transport for doing cross-domain connections with JSONP.



SignalR member

Are we still doing this for 0.4?





Don't really need JSONP solution.
<add name="Access-Control-Allow-Origin" solution in web.config is fine.

However the /signalr/hubs script should be more flexible, the url /signalr shouldn't be hardcoded

SignalR member

@Zyphrax you can change it via $.connection.hub.url there isn't a good default other than the relative path and that works for 90% of the cases

SignalR member

This was implemented as a contribution (Thanks @codeputty).

To make this work with Persistent connections:

var connection = $.connection('http://somecrossdomainurl/echo')

connection.start({ transport: 'longPolling', xdomain: true });

We may tweak the api (i.e try to autodetect so you don't need to specify longpolling) but this is the current implementation.

@davidfowl davidfowl was assigned Apr 6, 2012
@davidfowl davidfowl closed this Apr 6, 2012

Thanks for this! Does this mean though that xdomain only works with long polling and no other transport protocol? If so, is it technically possible for it to work with other protocols?

SignalR member

This feature is specifically about long polling. Other protocols aren't supported. You can check out CORS for an alternative to jsonp longpolling:


The CORS solution is working quite well. It becomes problematic when you have signalr on a subdomain, more than one subdomain using it and using cookies.

The specification says that you can specify multiple domains for Access-Control-Allow-Origin, but that doesn't seem to work when you have Access-Control-Allow-Credentials set to true (for cookie support).

My workaround is (in Global.asax.cs of my SignalR hubs MVC website):

/// <summary>
/// Raises when the application processes a request.
/// </summary>
protected void Application_BeginRequest(object sender, EventArgs e) {
    string origin = Request.Headers["Origin"];
    Uri uri;

    // Validate the Request origin
    if (Uri.TryCreate(origin, UriKind.Absolute, out uri) &&
        uri.Host.EndsWith(FormsAuthentication.CookieDomain)) {
        Response.AddHeader("Access-Control-Allow-Origin", uri.Scheme + "://" + uri.Authority);
        Response.AddHeader("Access-Control-Allow-Credentials", "true");

Another nice resource for CORS:


In AspNetHandler.cs I see that you've implemented it like this:

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");

This seems quite insecure. Now all origins are allowed. If you have a look at my code above you see that I compare the origin against the cookie domain. Could you implement something similar?

EDIT - one extra thing to note:
It would be better to somehow overwrite the Access-Control-Allow-Origin, instead of using AddHeader. Now if you have the Access-Control-Allow-Origin defined in your web.config, you'll end up with both values being sent to the client. Which will fail in almost all browsers (I think only Firefox supports that).

SignalR member
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment