ABP的语言及使用signalr

折磨人的跨域问题:

XMLHttpRequest cannot load https://api.taskexe.com/signalr/negotiate?clientProtocol=1.5&token=0J2rv2jZ…bpcommonhub"},{"name":"messagehub"}]&_=1488597450711. A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'https://taskexe.com' is therefore not allowed access. The credentials mode of an XMLHttpRequest is controlled by the withCredentials attribute.

意思大约是说,如果Cors使用通配符*则不允许使用 Access-Control-Allow-Credentials: true,两者是矛盾的。在signalr的跨域请求时,application_start中使用了,跨域:

 app.Map("/signalr", map =>
            {
                map.UseCors(CorsOptions.AllowAll);
//……
}

然后,signalr的链接就出现了这个矛盾,解决方法是,设置一个满足要求的Cors策略。但是signalr的请求如果携带cookie的话,都将失效。所以最好不要在signalr中携带cookie中。taskexe其实在signalr中携带了access token用来标明客户端身份,它是通过query string的方式传递的,是否合适有待商榷,最好的方式当然是放到请求的header头中,使用authorization的方式传递。

采取的办法是,构造一个Cors策略:

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 = true;
                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);
}

原本应该设置: policy.SupportsCredentials = false;但实际并没有起作用,后来设置成true,反而起了作用。我猜测源代码的逻辑应该是当 policy.SupportsCredentials = true;时,自动对policy.AllowAnyOrigin允许的Origin设置为对应的url地址,而不是通配符*。通过实际的调试,请求头返回的的确是这样的。

——————————————

ABP的语言问题,默认设置了taskexe这个application级别的区域语言,但是一直不生效:

<globalization culture="zh-CN" uiCulture="zh-CN"/>

郁闷了很久,突然在应用池级别做了同样的设置,然后就起了作用。优先级理解错误,似乎应用池的级别要比具体的网站级别高。

标签: cors,abp,signalr