首页 文章

在Azure上使用CORS的SignalR无法正常工作

提问于
浏览
3

我'm having trouble getting Signalr to support CORS on Azure. I' ve创建了MSDN Getting Started示例聊天程序,将其部署到Azure并确保它正常工作 . 然后我按照说明如何在SignalR Hubs API Guide - JavaScript Client中启用CORS,即我更改了Startup.cs以使用Microsoft.Owin.Cors并设置

map.UseCors(CorsOptions.AllowAll);

并在Win8上使用IE11进行了尝试 .

Signalr / IE正在发送CORS预检请求,如下所示:

Request OPTIONS /signalr/signalr/negotiate?connectionData=%5B%7B%22name%22%3A%22ommhub%22%7D%5D&clientProtocol=1.3&_=1398784789992 HTTP/1.1
Accept  */*
Origin  https://my.devserver.com
Access-Control-Request-Method   GET
Access-Control-Request-Headers  content-type, accept, x-requested-with
Accept-Encoding gzip, deflate
User-Agent  Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; Touch; LCJB; rv:11.0) like Gecko
Host    mytestsite.azurewebsites.net
Content-Length  0
DNT 1
Connection  Keep-Alive
Cache-Control   no-cache

而Azure正在返回几乎看起来正确的东西:

Response    HTTP/1.1 200 OK
Allow   OPTIONS, TRACE, GET, HEAD, POST
Content-Length  0
Server  Microsoft-IIS/8.0
Public  OPTIONS, TRACE, GET, HEAD, POST
X-Powered-By    ASP.NET
Set-Cookie  ARRAffinity=6115ee2c8e2594676e68d4f0ee51035a2;Path=/;Domain=mytestsite.azurewebsites.net
Date    Tue, 29 Apr 2014 15:23:43 GMT

但是浏览器在此之后永远不会发送任何内容(它应该请求连接) . 我怀疑这可能是因为预检响应不包括Access-Control-Allow-Origin标头 .

关于这一点,网上有很多相互矛盾的信息 . 有没有人成功地在Azure上使用CORS处理SignalR中心?如果你在那里,请告诉我们你是如何做到的 .

4 回答

  • 0

    我没有时间调试信号器代码,但我想出了一个解决方法 .

    我通过同一域中的URL代理Signalr请求,从而加载另一个服务(正确处理CORS) . 一旦OPTIONS预检请求由其他服务处理,IE允许所有进一步的请求在没有预检的情况下发生 .

  • 0

    对我来说,以下工作:

    app.Map("/signalr", map =>
    {
        map.UseCors(_corsOptions.Value);
        //map.UseCors(CorsOptions.AllowAll); // also ok but perhaps a little bit too open
        var hubConfiguration = new HubConfiguration
        {
            EnableDetailedErrors = false
        };
    
        map.RunSignalR(hubConfiguration);
    });
    

    使用_corsOptions.Value,如下所示:

    private static Lazy<CorsOptions> _corsOptions = new Lazy<CorsOptions>(() =>
    {
        return new CorsOptions
        {
            PolicyProvider = new CorsPolicyProvider
            {
                PolicyResolver = context =>
                {
                    var policy = new CorsPolicy();
                    policy.Origins.Add("http...");
                    policy.AllowAnyMethod = true;
                    policy.AllowAnyHeader = true;
                    policy.SupportsCredentials = true;
                    return Task.FromResult(policy);
                }
            }
        };
    });
    

    但不幸的是,这或多或少是您提到的样本中的代码不适合您 .

    你的web.config怎么样?它是干净的还是有CORS之类的东西

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

    我不记得究竟是否应该在那里 . 所以,如果它不起作用,它就在那里,删除它,否则你可以尝试添加它...

  • 0

    如果它可以帮助,在我这边,我用过:

    • map.UseCors(CorsOptions.AllowAll) ;

    • web.config 中没有customHeaders

    • 从我的Azure CORS Allowed-Origin中取消*(是的,我不得不把它取下来停止从我的本地js客户端获取跨域错误)

  • 0

    为了在 deployed to azure 时让信号灯工作,我不得不使用:

    • web.config中没有customHeaders

    • 使用corsoptions的corsop

    • appBuilder.SetDataProtectionProvider

    关于2:内部启动配置:

    appBuilder.Map("/signalr", map =>
     {
        var corsOptions = new Microsoft.Owin.Cors.CorsOptions
        {
           PolicyProvider = new CorsPolicyProvider
           {
              PolicyResolver = context => ResolvePolicy()
           }
       };
       map.UseCors(corsOptions);
     }
    

    使用ResolvePolicy():

    private Task<System.Web.Cors.CorsPolicy> ResolvePolicy() {
    
            var corsPolicy = new System.Web.Cors.CorsPolicy()
            {
                AllowAnyMethod = true,
                AllowAnyHeader = true,
                SupportsCredentials = true
            };
    
            corsPolicy.Origins.Add("http://ng2a-hneu-web-ui.azurewebsites.net");
            corsPolicy.Origins.Add("http://localhost:3000");
    
            return Task.FromResult(corsPolicy);
        }
    

    大约3:在startup.cs里面,配置()

    appBuilder.SetDataProtectionProvider(new MachineKeyProtectionProvider());
    

    这是gist的链接 .

    我在 official signalr github 找到了解决方案 .
    点击此链接:ASP.NET 5 app in Azure doesn't work with SignalR .

    仅在部署到Azure时才会出现此问题 . 在开发模式下,使用ISS表达似乎一切正常 .

    添加允许的原点时,非常重要的一点是不要使用 slash 进行后缀 .

    corsPolicy.Origins.Add("http://xxxx**/**"); //incorrect
    corsPolicy.Origins.Add("http://xxx); //correct
    

相关问题