Chrome中SignalR和跨域请求的问题27

时间:2013-06-27 13:27:36

标签: asp.net-mvc iis-7 cross-domain signalr

编辑:这显然只是Chrome中的一个问题,它在FF和IE中运行良好

Chrome版本:27.0.1453.116

我在localhost:13371上有一个简单的JS / HTML站点,我正在尝试访问localhost:13371上的SignalR中心。

每当发出请求时,我都会收到以下错误:

  

XMLHttpRequest无法加载http://localhost:13370/signalr/hubs/negotiate?_=1372338722032。 Access-Control-Allow-Origin不允许原点http://localhost:13371

我已经尝试过了:

  • Application_Start上启用SignalR上的跨域:

    RouteTable.Routes.MapHubs(new HubConfiguration { EnableCrossDomain = true });
    
  • 在SignalR服务器的Web.Config中启用跨域:

    <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>
    
  • 在JavaScript中设置信号器中心的连接URL:

    $.connection.hub.url = 'http://localhost:13370/signalr/hubs';
    
  • 在jQuery中启用CORS:

    $.support.cors = true;
    
  • 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();
        }
    }
    

以上都没有,也没有上述任何组合起作用。

其他信息:

  • 两个站点都在Windows 7上的IIS中运行
  • SignalR站点在端口13370上运行,作为.NET 4.0下MVC 4站点的一部分。
  • JS / HTML站点是端口13371上的简单Web服务器,根本没有托管代码。
  • SignalR网站肯定会回应浏览器对相关资源的直接请求。
  • SignalR版本为1.1.2

5 个答案:

答案 0 :(得分:5)

编辑:我现在找到了两个解决方案......

方法1.摆脱你可能不需要的垃圾:

正如我在Stack Overflow question中发现的那样,基本上我在上面列出的“我尝试过的东西”中添加的几乎所有内容都是不必要的。修复步骤:

  1. 删除我在上面尝试过的所有内容。这意味着在Web.Config或其他地方(如Global.asax,没有自定义jquery设置等)根本没有指定自定义标头。

  2. .. RouteTable.Routes.MapHubs(new HubConfiguration { EnableCrossDomain = true });除外Application_Start

  3. 此外,您仍需要设置$.connection.hub.url = 'http://localhost:13370/signalr/hubs';

  4. ......就是这样。 这可能是我最终使用的最佳解决方案。

    方法2.如果您在Chrome中仍然遇到问题,请使用jsonp:

    如果你在Chrome中仍然遇到这样的问题,可以使用jsonp让协商脚本正确下载...将以下内容添加到我的JavaScript中心开始解决问题:

    //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
    });
    

    可能有更好的方法来测试浏览器功能并相应地设置jsonp ...看着用户代理感觉很脏......但是这解决了我在过渡时期的问题。我希望这有助于其他人。

答案 1 :(得分:1)

这对我有用。将此方法放在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);
    }
}

答案 2 :(得分:1)

我在MVC6 SignarR服务器上遇到了同样的问题。 刚刚在程序包管理器控制台&amp;中安装了Install-Package Microsoft.Owin.Cors在Startup.cs中添加了app.UseCors(CorsOptions.AllowAll)

答案 3 :(得分:0)

这是在文档中,但从不这样做:

$ .support.cors = true;

答案 4 :(得分:0)

对我有用的是。

protected void Application_Start(object sender, EventArgs e)
    {
        var config = new HubConfiguration
        {
            EnableCrossDomain = true
        };
        RouteTable.Routes.MapHubs(config);
    }
    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        if (this.Context.Request.Path.Contains("signalr/"))
        {
            this.Context.Response.AddHeader("Access-Control-Allow-Headers", "accept,origin,authorization,content-type");
        }
    }