You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React网站如何与启用HTTP/2的ASP.NET 6服务器通信?

问题描述

我正在学习Web技术,搭建了一套包含以下组件的项目:

  • 提供gRPC服务与REST API的ASP.NET 6服务器
  • 作为桌面gRPC客户端的.NET 6 WPF应用
  • 作为移动端gRPC客户端的.NET 6 MAUI应用
  • 通过REST与服务器通信的React网站

目前服务器和WPF、MAUI客户端的gRPC通信正常,但在把REST API集成到原本只支持gRPC的服务器后,React网站无法和服务器通信。

服务器配置

appsettings.json

{
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Information"
        }
    },
    "AllowedHosts": "*",
    "Kestrel": {
        "EndpointDefaults": {
            "Protocols": "Http2"
        }
    }
}

launchSettings.json

{
    "$schema": "https://json.schemastore.org/launchsettings.json",
    "iisSettings": {
        "windowsAuthentication": false,
        "anonymousAuthentication": true,
        "iisExpress": {
            "applicationUrl": "http://localhost:18460",
            "sslPort": 44326
        }
    },
    "profiles": {
        "Gather.Server": {
            "commandName": "Project",
            "dotnetRunMessages": true,
            "launchBrowser": false,
            "launchUrl": "weatherforecast",
            "applicationUrl": "https://localhost:7081;http://localhost:5081",
            "environmentVariables": {
                "ASPNETCORE_ENVIRONMENT": "Development"
            }
        },
        "IIS Express": {
            "commandName": "IISExpress",
            "launchBrowser": false,
            "launchUrl": "weatherforecast",
            "environmentVariables": {
                "ASPNETCORE_ENVIRONMENT": "Development"
            }
        }
    }
}

Program.cs

public static IHostBuilder CreateHostBuilder(string[] args)
{
    // This retrieves the proper IP address and port numbers that are used below.
    var configuration = ServiceFactory.Instance.GetConfiguration();

    return Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.ConfigureKestrel(options =>
        {
            // http://192.168.1.20:5000
            options.Listen(configuration.IPAddress, configuration.HttpPort);
            
            // https://192.168.1.20:5005
            options.Listen(configuration.IPAddress, configuration.HttpsPort, configure => configure.UseHttps());
        });

        webBuilder.UseStartup<Startup>();
    });
}

Startup.cs

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddGrpc(options =>
        {
            options.MaxReceiveMessageSize = 16 * 1024 * 1024;
            options.MaxSendMessageSize = 16 * 1024 * 1024;
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGrpcService<AuthenticationService>();

            var summaries = new[]
            {
                "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
            };

            endpoints.MapGet("/weatherforecast", () =>
            {
                return Enumerable.Range(1, 5).Select(index => new WeatherForecast(DateTime.Now.AddDays(index), Random.Shared.Next(-20, 55), summaries[Random.Shared.Next(summaries.Length)]))
                                             .ToArray();
            });
        });
    }
}

React客户端配置

React项目是Visual Studio 2022中创建的「Standalone JavaScript React Project」,仅修改了setupProxy.js:

setupProxy.js

const { createProxyMiddleware } = require('http-proxy-middleware');

const context = [
    "/weatherforecast",
];

module.exports = function (app) {
    const appProxy = createProxyMiddleware(context, {
        target: 'https://192.168.1.20:5005',
        secure: false,
        changeOrigin: true,
        logLevel: 'debug'
    });

    app.use(appProxy);
};

错误情况

  • 使用HTTPS时:启动React网站出现连接错误
  • 使用HTTP时:服务器控制台无错误,但Node控制台出现错误

我刚接触React/Node/REST,希望能解决这个通信问题。


解决方案

核心问题:HTTP/2 兼容性

服务器配置里,appsettings.json 把Kestrel的默认协议设为了Http2,但React代理和大多数浏览器的REST请求默认使用HTTP/1.1,HTTP/2在纯文本(非TLS)场景下支持有限,且部分代理工具对HTTP/2的支持不完善,这是导致通信失败的主要原因。

修复步骤

  1. 调整Kestrel协议配置
    修改appsettings.json,给HTTP和HTTPS端点分别指定协议,让HTTP端点支持HTTP/1.1,HTTPS端点同时支持HTTP/1.1和HTTP/2:

    "Kestrel": {
        "Endpoints": {
            "Http": {
                "Url": "http://192.168.1.20:5000",
                "Protocols": "Http1"
            },
            "Https": {
                "Url": "https://192.168.1.20:5005",
                "Protocols": "Http1AndHttp2"
            }
        }
    }
    

    或者保留Program.cs中的代码配置,在Listen时指定协议:

    options.Listen(configuration.IPAddress, configuration.HttpPort, listenOptions =>
    {
        listenOptions.Protocols = HttpProtocols.Http1;
    });
    options.Listen(configuration.IPAddress, configuration.HttpsPort, listenOptions =>
    {
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
        listenOptions.UseHttps();
    });
    
  2. 更新React代理配置
    如果使用HTTP测试,把代理目标改成HTTP地址:

    target: 'http://192.168.1.20:5000',
    

    如果用HTTPS,先通过dotnet dev-certs https --trust命令信任开发环境证书,代理配置保持secure: false即可。

  3. 添加CORS支持
    服务器本身配置CORS可避免潜在跨域问题,在Startup.cs的ConfigureServices中添加:

    services.AddCors(options =>
    {
        options.AddPolicy("AllowAll", policy =>
        {
            policy.AllowAnyOrigin()
                  .AllowAnyMethod()
                  .AllowAnyHeader();
        });
    });
    

    然后在Configure中,路由前启用CORS:

    app.UseCors("AllowAll");
    app.UseRouting();
    
  4. 验证端点可达性
    先直接在浏览器访问http://192.168.1.20:5000/weatherforecast或https://192.168.1.20:5005/weatherforecast,确认服务器能正常返回数据后,再测试React应用。


内容的提问来源于stack exchange,提问作者GameDevAlien

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 04:20:27