c# - WebSocket 握手错误 : Unexpected response code 400

标签 c# angular web asp.net-core

我为他准备了 Web API 和 Angular 应用。

我在 web api 端启用了 cors 策略:

services.AddCors(options =>
            {
                options.AddPolicy("CorsPolicy", b =>
                    {
                        b.AllowAnyOrigin()
                            .AllowAnyMethod()
                            .AllowAnyHeader()
                            .AllowCredentials();
                    }
                );
            });

app.UseCors("CorsPolicy");

我像这样从 Angular 发送获取请求:

this._httpClient.get(`WebApi link`);

但捕获错误:

Error during WebSocket handshake: Unexpected response code 400

我做错了什么?

这个链接在 PostMan 中完美运行,我得到了结果。

Web API 使用 win auth。

UPD

Web API 端在 Startup.cs 中有此设置:

public class Startup
{
    private readonly ILoggerFactory _loggerFactory;  
    public Startup(IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        AutomapperConfig.Init();

        _loggerFactory = loggerFactory;
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddEnvironmentVariables();
        Configuration = builder.Build();
    }   
    public IConfigurationRoot Configuration { get; }

    /// <summary>
    /// This method gets called by the runtime. Use this method to add services to the container.
    /// </summary>
    /// <param name="services"></param>
    /// <returns></returns>
    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.AddResponseCompression();
        services.AddMvc();
        services.AddAuthentication(HttpSysDefaults.AuthenticationScheme);
        services.AddAuthorization(options =>
        {
            foreach (var action in Action.All)
                options.AddPolicy(action.Name, policy =>
                    policy.Requirements.Add(new AssemblyStorageRequirement(action)));
        });
        services.AddSingleton<IAuthorizationHandler, AssemblyStorageRequirementHandler>();

        services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy", b =>
                {
                    b.AllowAnyOrigin()
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        .AllowCredentials();
                }
            );
        });

        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
            var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
            var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
            c.IncludeXmlComments(xmlPath);
        });
        services.AddOptions();   
        services.AddSingleton(Configuration);   // IConfigurationRoot
        services.AddSingleton<IConfiguration>(Configuration);       // IConfiguration explicitly                          
        return services.AddDiConfig(Configuration);
    }

    /// <summary>
    /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    /// </summary>
    /// <param name="app"></param>
    /// <param name="env"></param>
    /// <param name="loggerFactory"></param>
    /// <param name="appLifetime"></param>
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime appLifetime)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();
        loggerFactory.AddLog4Net();
        app.UseSwagger();
        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
        });
        app.UseAuthentication();
        app.UseResponseCompression();
        app.UseCors("CorsPolicy");
        app.UseMvc();

        app.UseForwardedHeaders(new ForwardedHeadersOptions
        {
            ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
        });   
        appLifetime.ApplicationStopped.Register(DiConfig.DisposeContainer);
    }
}

Angular 端在 Startup.cs 中有这个设置:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

        // In production, the Angular files will be served from this directory
        services.AddSpaStaticFiles(configuration =>
        {
            configuration.RootPath = "ClientApp/dist";
        });
        services.AddCors(options =>
        {
            options.AddPolicy("CorsPolicy", b =>
                {
                    b.AllowAnyOrigin()
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        .AllowCredentials();
                }
            );
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }
        app.UseCors("CorsPolicy");
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseSpaStaticFiles();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller}/{action=Index}/{id?}");
        });

        app.UseSpa(spa =>
        {
            // To learn more about options for serving an Angular SPA from ASP.NET Core,
            // see https://go.microsoft.com/fwlink/?linkid=864501

            spa.Options.SourcePath = "ClientApp";

            if (env.IsDevelopment())
            {
                spa.UseAngularCliServer(npmScript: "start");
            }
        });
    }
}

Request Headers: GET wss://localhost:44391/sockjs-node/616/kjiu00aa/websocket HTTP/1.1 Host: localhost:44391 Connection: Upgrade Pragma: no-cache Cache-Control: no-cache Upgrade: websocket Origin: https://localhost:44391 Sec-WebSocket-Version: 13 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36 Accept-Encoding: gzip, deflate, br Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7 Sec-WebSocket-Key: Ia0VO1G8+d52FJG74UvsQw== Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

Response Headers:

HTTP/1.1 400 Bad Request Transfer-Encoding: chunked Vary: Origin Server: Kestrel Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: https://localhost:44391 X-SourceFiles: =?UTF-8?B?RTpcUHJvamVjdHNcVEZTXE9jdG9wdXNTZXJ2aWNlc1xBc3NlbWJseVN0b3JhZ2VcQXNzZW1ibHlTdG9yYWdlV2ViU2l0ZVxBc3NlbWJseVN0b3JhZ2VXZWJTaXRlXHNvY2tqcy1ub2RlXDYxNlxraml1MDBhYVx3ZWJzb2NrZXQ=?= X-Powered-By: ASP.NET Date: Fri, 15 Mar 2019 08:03:32 GMT

General:

Request URL: wss://localhost:44391/sockjs-node/616/kjiu00aa/websocket Request Method: GET Status Code: 400 Bad Request

UPD

如果我注释掉代码中唯一使用 HttpClient 的地方,那么错误仍然显示...

所以问题不在WebApi

最佳答案

你可以这样试试吗

    services.AddCors(options =>
    {
        options.AddPolicy("CorsPolicy",
            builder => builder.AllowAnyOrigin()
              .AllowAnyMethod()
              .AllowAnyHeader()
              .AllowCredentials()
        .Build());
    });

关于c# - WebSocket 握手错误 : Unexpected response code 400,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55170623/

相关文章:

c# - 如何使用提供的凭据调用 SSPI 的 'AcquireCredentialsHandle'?

c# - ML.NET,缺少 "Score Column"

javascript - ionic2 - 仅当用户在 Toast 中单击 "close"时才创建函数

angular - 在哪里可以找到旧版本的 Angular 2 文档?

angular - Cypress 中的 'ng' 是什么

javascript - 如何在每次保存后自动运行Webpack-dev-server?

c# - 如果我正在实现 IEquatable<T>,那么覆盖 Equals 是否重要?

html - 如何在 HTML/CSS 中更改 div 的背景颜色

php - 为什么我无法使用 php 访问 mysql?

c# - 从数据表中删除具有行值的列