gpt4 book ai didi

asp.net-web-api - 协商后跨源SignalR连接停止

转载 作者:行者123 更新时间:2023-12-04 14:43:51 28 4
gpt4 key购买 nike

我有一个提供 View 的MVC 5应用程序,以及一个作为服务层(.NET 4.5)的Web API 2应用程序。 Web API应用程序在处理POST到服务API时使用SignalR 2.1.2返回进度。两者被部署到不同的域,因此我根据asp.net教程文章设置了跨源支持。

[assembly: OwinStartup(typeof (Startup))]
namespace MyApp.Service
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Map("/signalr", map =>
{
//worry about locking it down to specific origin later
map.UseCors(CorsOptions.AllowAll);
map.RunSignalR(new HubConfiguration());
});
//now start the WebAPI app
GlobalConfiguration.Configure(WebApiConfig.Register);
}
}
}

WebApiConfig.cs还包含其自己的CORS声明。

namespace MyApp.Service
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//controller invocations will come from the MVC project which is deployed to a
//different domain, so must enable cross origin resource sharing
config.EnableCors();
// Web API routes
config.MapHttpAttributeRoutes();

//Snip other controller dependency initialisation
}
}
}

我定义了一个没有服务器端API的简单集线器类(仅允许服务器将其推送到客户端,而不允许客户端调用)。

namespace MyApp.Service.Hubs
{
[HubName("testresult")]
public class TestResultHub : Hub
{
}
}

由于我要跨域并且集线器没有公开任何服务器端API,因此我不必费心使用生成的JS代理。

设置信号中心集线器连接的JS的相关位是:(请记住,这是从MVC应用提供的,该MVC应用没有任何信号支持(当然jquery-signalr- {version} .js除外))

function TestScenarioHandler(signalrHubUrl) {
var self = this;
//Snip irrelevant bits (mostly Knockout initialisation)

self.signalrConnectionId = ko.observable();

var hubConnection = $.hubConnection(signalrHubUrl, { useDefaultPath: false });

var hubProxy = hubConnection.createHubProxy("testresult");
hubProxy.on("progress", function(value) {
console.log("Hooray! Got a new value from the server: " + value);
});

hubConnection.start()
.done(function() {
self.signalrConnectionId(hubConnection.id);
console.log("Connected to signalr hub with connection id " + hubConnection.id);
})
.fail(function() {
console.log("Failed to connect to signalr hub at " + hubConnection.url);
});
}

像这样跨域,Firefox网络流量显示了一个GET到(我已经确认Chrome显示了相同的东西)
http://****service.azurewebsites.net/signalr/negotiate?clientProtocol=1.5&connectionData=[{"name":"testresult"}]&_=1424419288550
请注意, name与我的集线器类上 HubName属性的值匹配。

此GET返回HTTP 200,响应给了我一个JSON负载,其中包含 ConnectionIdConnectionToken和一堆其他字段,表明一切正常。 HTTP响应还将 Access-Control-Allow-Origin: header 设置为GET所源自的域。一切看起来都不错,除了那边的交通停了。

但是JS控制台会打印 "Failed to connect to signalr hub at http://****service.azurewebsites.net/signalr"
为了验证我没有做任何愚蠢的事情,我向MVC应用程序添加了Signalr支持和基本集线器(因此不需要交叉源),并相应地更改了 $.hubConnection()hubConnection.createProxy()调用。当我这样做时,浏览器流量将显示相同的 /signalr/negotiate?... GET(显然不再跨源),然后还会显示GET到 /signalr/connect?.../signalr/start?...。 JS控制台还会打印成功消息。

总而言之,

在服务层上启用了
  • CORS,信号器/negotiate GET返回200,看似有效的连接ID和预期的Access-Control-Allow-Origin: header 。这向我暗示了服务器端CORS支持本身的行为正确,但信号器连接未成功。
  • 当我重新配置以使信号器连接不是跨源的时,一切都会按预期进行。

  • 我想念WTF或做错了吗? HttpConfiguration.EnableCors()IAppBuilder.UseCors(CorsOption)之间可能存在一些冲突?

    最佳答案

    解决了。我已经将map.UseCors(CorsOptions.AllowAll)改为传递CorsPolicy对象,并将SupportsCredentials设置为false,在其他地方已经读到Access-Control-Allow-Origin: *access-control-allow-credentials: true不兼容。

    private static readonly Lazy<CorsOptions> SignalrCorsOptions = new Lazy<CorsOptions>(() =>
    {
    return new CorsOptions
    {
    PolicyProvider = new CorsPolicyProvider
    {
    PolicyResolver = context =>
    {
    var policy = new CorsPolicy();
    policy.AllowAnyOrigin = true;
    policy.AllowAnyMethod = true;
    policy.AllowAnyHeader = true;
    policy.SupportsCredentials = false;
    return Task.FromResult(policy);
    }
    }
    };
    });

    public void Configuration(IAppBuilder app)
    {
    app.Map("/signalr", map =>
    {
    map.UseCors(SignalrCorsOptions.Value);
    map.RunSignalR(new HubConfiguration());
    });
    //now start the WebAPI app
    GlobalConfiguration.Configure(WebApiConfig.Register);
    }

    SupportCredentials设置为true会导致 Access-Control-Allow-Origin header 用响应中的实际原点(不是 *)和 access-control-allow-credentials: true重写。

    现在就可以了。

    关于asp.net-web-api - 协商后跨源SignalR连接停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28624724/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com