【问题标题】:Signalr CORS issue信号器 CORS 问题
【发布时间】:2015-01-20 22:56:58
【问题描述】:

在我的服务器端,我使用带有信号器的 web api 2。 在我的客户端,我使用的是 angularjs。

这是我启动信号器连接时的 http 请求:

> GET
> http://example.com/signalr/negotiate?clientProtocol=1.4&connectionData=%5B%7B%22name%22%3A%22main%22%7D%5D&_=1416702959615 HTTP/1.1 Host: mysite.net Connection: keep-alive Pragma: no-cache
> Cache-Control: no-cache Accept: text/plain, */*; q=0.01 Origin:
> http://lh:51408 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64)
> AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65
> Safari/537.36 Content-Type: application/x-www-form-urlencoded;
> charset=UTF-8 Referer: http://localhost:51408/ Accept-Encoding: gzip,
> deflate, sdch Accept-Language: en-US,en;q=0.8 Cookie:
> ARRAffinity=9def17406de898acdc2839d0ec294473084bbc94a8f600c867975ede6f136080

然后回应:

> HTTP/1.1 200 OK Cache-Control: no-cache Pragma: no-cache
> Transfer-Encoding: chunked Content-Type: application/json;
> charset=UTF-8 Expires: -1 Server: Microsoft-IIS/8.0
> X-Content-Type-Options: nosniff X-AspNet-Version: 4.0.30319
> X-Powered-By: ASP.NET Date: Sun, 23 Nov 2014 00:36:13 GMT
> 
> 187
> {"Url":"/signalr","ConnectionToken":"6BKcLqjNPyOw4ptdPKg8jRi7xVlPMEgFUdzeJZso2bnXliwfY4WReQWHRpmB5YEZsbg14Au7AS5k5xS5/4qVheDxYoUkOjfFW0W8eAQsasjBaSQOifIilniU/L7XQ1+Y","ConnectionId":"f2fc7c47-c84f-49b8-a080-f91346dfbda7","KeepAliveTimeout":20.0,"DisconnectTimeout":30.0,"ConnectionTimeout":110.0,"TryWebSockets":true,"ProtocolVersion":"1.4","TransportConnectTimeout":5.0,"LongPollDelay":0.0}
> 0

但是,在我的 javascript 中,我在连接时收到以下错误响应:

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhos:51408' is therefore not allowed access.

在我的服务器端,我的启动方法如下所示:

public void Configuration(IAppBuilder app)
{
    System.Web.Mvc.AreaRegistration.RegisterAllAreas();
    ConfigureOAuth(app);
    GlobalConfiguration.Configure(WebApiConfig.Register);
    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
}

这不应该确保在信号器中也使用 cors 还是我遗漏了什么?

【问题讨论】:

    标签: asp.net angularjs signalr cors


    【解决方案1】:

    对于那些对 Angular、SignalR 2.0 和 Web API 2.2 有同样问题的人,

    我能够通过在 web.config添加 cors 配置 并在 webapiconfig 中没有它们来解决这个问题。 csstartup.cs

    <system.webServer> 下的 web.config 更改如下

    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="http://localhost" />
        <add name="Access-Control-Allow-Methods" value="*" />
        <add name="Access-Control-Allow-Credentials" value="true" />
      </customHeaders>
    </httpProtocol>
    

    【讨论】:

    • 你知道为什么这是唯一有效的方法吗? ;) 我尝试了 Louis Lewis 的上述回答,但没有奏效。
    • 经过大量搜索,这个解决方案解决了我的问题。我使用的是 SignalR 2.2。
    • 这在生产环境中也适用于我。 == IIS(天蓝色应用服务)
    【解决方案2】:

    你可以从这里https://github.com/louislewis2/AngularJSAuthentication/blob/master/AngularJSAuthentication.API/Startup.cs看这个sn-p 看看能不能帮到你。

    public void Configuration(IAppBuilder app)
        {
            HttpConfiguration config = new HttpConfiguration();
    
            ConfigureOAuth(app);
    
            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
                {
                    // You can enable JSONP by uncommenting line below.
                    // JSONP requests are insecure but some older browsers (and some
                    // versions of IE) require JSONP to work cross domain
                    //EnableJSONP = true
                    EnableDetailedErrors = true
                };
                // Run the SignalR pipeline. We're not using MapSignalR
                // since this branch already runs under the "/signalr"
                // path.
                map.RunSignalR(hubConfiguration);
            });
    
            WebApiConfig.Register(config);
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            app.UseWebApi(config);
            Database.SetInitializer(new MigrateDatabaseToLatestVersion<AuthContext, AngularJSAuthentication.API.Migrations.Configuration>());
    
        }
    

    【讨论】:

    • 谢谢,但在我试图解决这个问题的几个小时内,我已经尝试过了。
    • 在您的问题中,这是一个错字吗:'localhos:51408' 您在错误消息中指出 javascript 正在抛出。我看到它缺少一个“t”,您是否可能在客户列表中输入错误?
    • 我想我应该提到 - 由于 stackoverflows 出色的政策,我不得不稍微更改一下网址。不过,这不是一个错字。
    • 我了解,为了能够帮助确定问题的原因,我需要查看您的客户端/令牌配置服务器端。还有您的信号器客户端设置。您使用的是与我的链接中相同的授权系统吗?
    【解决方案3】:

    我在 MVC.net 中遇到过 CORS 问题

    问题是 SignalR negoiate XHR 请求是使用凭据发出的 = 包括因此请求总是发送用户 cookie

    服务器必须回复响应标头 Access-Control-Allow-Credentials 设置为 true

    第一种方法,这是由于其他人的帮助,在 web.config 中配置它

    <configuration>
        <system.webServer>
            <httpProtocol>
               <customHeaders>
                  <add name= "Access-Control-Allow-Origin" value="http://yourdomain:port"/>
                  <add name="Access-Control-Allow-Credentials" value = "true"/>
               </customHeaders>
            </httpProtocol>
        </system.webServer>
    </configuration>
    

    我努力使它工作的第二种方法是通过使用 OWIN CORS 的代码

    [assembly::OwinStartup(typeof(WebHub.HubStartup), "Configuration"]
    namespace WebHub
    {
    public class HubStartUp
    {
        public void Configuration(IAppBuilder app)
        {
            var corsPolicy = new CorsPolicy
            {
                AllowAnyMethod = true,
                AllowAnyHeader = true,
                SupportsCredentials = true,
            };
    
            corsPolicy.Origins.Add("http://yourdomain:port");
    
            var corsOptions = new CorsOptions
            {
                PolicyProvider = new CorsPolicyProvider
                {
                    PolicyResolver = context =>
                    {
                        context.Headers.Add("Access-Control-Allow-Credentials", new[] { "true" });
                        return Task.FromResult(corsPolicy);
                    }
                }
            };
    
            app.Map("/signalR", map =>
            {
                map.UseCors(corsOptions);
                var config = new HubConfiguration();
                map.RunSignalR(config);
            });
        }
    }}
    

    【讨论】:

    • 第二种方法对我不起作用。允许的来源设置为呈现发出请求的页面的任何 URL。
    • 另外context 对象是请求,而不是响应,所以添加"Access-Control-Allow-Credentials" 不会对响应做任何事情。
    【解决方案4】:

    在 ConfigureServices 方法中:

    services.AddCors(options => options.AddPolicy("CorsPolicy", builder =>
                     {
                        builder.AllowAnyHeader()
                               .AllowAnyMethod()
                               .SetIsOriginAllowed((host) => true)
                               .AllowCredentials();
                     }));
    

    在配置方法中:

    app.UseCors("CorsPolicy");
    app.UseSignalR(routes =>
                   {
                      routes.MapHub<General>("/hubs/general");
                   });
    

    【讨论】:

      猜你喜欢
      • 2014-09-19
      • 1970-01-01
      • 2016-07-28
      • 1970-01-01
      • 1970-01-01
      • 2021-12-05
      • 1970-01-01
      • 1970-01-01
      • 2016-06-10
      相关资源
      最近更新 更多