Azure 上 SignalR 2.2 的 CORS 问题

CORS issue with SignalR 2.2 on Azure

我正在尝试从我的 Angular2 连接 SignalR 以进行消息传递。

我在 chrome 中遇到错误:

XMLHttpRequest cannot load https://ls-dev-signalr.azurewebsites.net/signalr/negotiate?clientProtocol=1…onData=%5B%7B%22name%22%3A%22realtimemessaginghub%22%7D%5D&_=1490197517724. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

我的 SignalR 配置在 OWIN 启动文件中,如下所示:

public void Configuration(IAppBuilder app)
{
    var config = new HttpConfiguration();

    var corsOption = new CorsOptions
        {
            PolicyProvider = new CorsPolicyProvider
            {
                PolicyResolver = context =>
                {
                    var policy = new CorsPolicy { AllowAnyOrigin = true, AllowAnyHeader = true, AllowAnyMethod = true };

                    return Task.FromResult(policy);
                }
            }
        };

    app.Map("/signalr", map =>
    {
        var hubConfiguration = new HubConfiguration
            {
                EnableDetailedErrors = false,
                //EnableJSONP = true,
                EnableJavaScriptProxies = true,
            };
       map.UseCors(corsOption).RunSignalR(hubConfiguration);
    });

    app.UseCors(corsOption);
    WebApiConfig.Register(config);
    app.UseWebApi(config);

}

我研究了很多 SO 帖子,但没有任何成功。

我应该如何为 SignalR 启用 CORS?

@ShaulBehr 的更新,他正在与 OP 合作解决此问题:

我们已将问题缩小为浏览器客户端在发出 SignalR 连接请求时未发送 Origin header。我们可以在 Postman 中重现此行为:如果您发送 Origin header,SignalR 端点会响应 Access-Control-Allow-Origin header。没有就没有。

现在的问题(悬赏)是:

我一直发现将此部分添加到 web.config 文件效果最好:

 <system.webServer>
   <httpProtocol>
     <customHeaders>
       <add name="Access-Control-Allow-Origin" value="*" />
       <add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,OPTIONS" />
     </customHeaders>
   </httpProtocol>
 </system.webServer>

注意:这些设置是 "wide-open",接受任何呼叫者。您可能需要对您的用例进行更多限制。

希望对您有所帮助!

我正在使用 SignalR 跨域,并且也在使用 v2.2。不过,我使用的是 Angular 1.5。但如果问题确实出在 SignalR 端,那么这应该可行。

  app.Map("/signalr", map =>
     {
        // Setup the CORS middleware to run before SignalR.
        // By default this will allow all origins. You can 
        // configure the set of origins and/or http verbs by
        // providing a cors options with a different policy.
        map.UseCors(CorsOptions.AllowAll);
        var hubConfiguration = new HubConfiguration
        {
           EnableDetailedErrors = true
        };
        map.RunSignalR(hubConfiguration);
     });

根据 HTTP 规范(下面的URL):

While following the requirements for cross-site access requests, user agents must ensure that for each request (including redirects, et cetera) the Origin HTTP request header is set, with the value set to access control origin.

https://www.w3.org/TR/2008/WD-access-control-20080912/#cross-site0

IIS 在这方面尊重规范,如果设置了 Origin 请求 header,则仅发送 Access-Control-Allow-Origin header。

话虽如此,即使不推荐,也可以强制服务器始终为每个请求设置 Access-Control-Allow-Origin header,方法是将其添加为自定义 header在你的 web.config 文件中。 您还必须删除 Azure 门户中 Cors blade 中的任何条目。

为此,您可以将以下部分添加到 web.config 文件中:

<configuration>
  <system.webServer>
    <httpProtocol>
         <customHeaders>
            <add name="Access-Control-Allowed-Origin" value="*" />
         </customHeaders>
    </httpProtocol>
  </system.webServer>
</configuration>