当前位置: 首页 > 知识库问答 >
问题:

NET5.0 Blazor WASM CORS客户端异常

公西鸿博
2023-03-14

我有一个Blazor WASM应用程序和一个网络应用程序接口,通过HttpClient被Blzor调用。这两个程序运行在同一台机器上(也在正式生产环境中,对于小型企业应用程序来说,这不应该是异国情调!)。

从Blazor客户端调用Web Api会导致客户端CORS异常

CORS策略阻止从http://localhost:4040/https://localhost:5001获取数据:请求的资源上不存在访问控制允许来源标头。如果不透明的响应满足您的需求,请将请求的模式设置为no-cors,以在禁用CORS的情况下获取资源。

这是本案的预期行为。

在我以前用PHP开发的一个api项目中,它有相同的客户端行为,我可以通过简单地设置响应头(例如)来绕过CORS异常。

$response = new Response;
$response->setState(false, $route->command);
...
header("Access-Control-Allow-Origin: *");
echo $response;

现在我想在我的.NET5.0WebAPI中使用它。我在互联网上找到了不同的文档来处理这个问题

https://docs.microsoft.com/de-de/aspnet/core/security/cors?view=aspnetcore-5.0 https://www.c-sharpcorner.com/article/enabling-cors-in-asp-net-core-api-application/ https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.cors.infrastructure.corspolicybuilder.withorigins?view=aspnetcore-5.0

并在我的api中实现了它

    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
                        .AddCors()
                        .AddSwaggerGen(c => c.SwaggerDoc("v1", new OpenApiInfo { Title = "api", Version = "v1"}) )
                        .AddControllers()
                        ;
        //---------------------------------------------------------------------

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure
                    (
                        IApplicationBuilder app,
                        IWebHostEnvironment env
                    )
                    =>  app.
                        apply( _ =>
                        {
                            if (true) //(env.IsDevelopment())
                            {
                                app
                                .UseDeveloperExceptionPage()
                                .UseSwagger()
                                .UseSwaggerUI( c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "api v1") );
                            }
                        })
                        .UseCors( cors =>
                            cors
                            .AllowAnyHeader()
                            .AllowAnyMethod()
                            .SetIsOriginAllowed( _ => true )
                            .AllowCredentials()
                        )
                        .UseHttpsRedirection()
                        .UseRouting()
                        .UseAuthorization()
                        .UseEndpoints( e => e.MapControllers() )
                        ;
        //---------------------------------------------------------------------
    }

甚至尝试在ApicController中设置响应头

    [Route("/")]
    [ApiController]
    public sealed class ServertimeController : ControllerBase
    {
        //[EnableCors("AllowOrigin")]
        [HttpGet]
        public Servertime Get() {

            Response.Headers.Add("Access-Control-Allow-Origin", "*");
            Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT");

            return servertime();
        }
    }

Blazor WASM客户端看起来像

    private async void onClick()
    {

        var response = await httpClient.GetFromJsonAsync<Servertime> ("http://localhost:4040");
        message = response.servertime;
        this.StateHasChanged();
    }

但它仍然会导致客户端CORS异常。为了在开发中绕过这一点,我使用浏览器扩展“CORS Unblock”,但这不是部署的选项。

避免Blazor客户端异常的正确方法是什么?我错过了什么?

共有3个答案

公孙国兴
2023-03-14
var client = new HttpClient();

var request = new HttpRequestMessage
{
    Method = new HttpMethod("GET"),
    RequestUri = new Uri($"{site.BaseUrl}robots.txt")
};

request.Headers.Add("Accept", "text/plain");
request.SetBrowserRequestMode(BrowserRequestMode.NoCors);

var response = await client.SendAsync(request);

var txt = await response.Content.ReadAsStringAsync();

工具书类

  • SetBrowserRequestMode
  • 浏览器请求模式
羊舌涵涤
2023-03-14

只需将此添加到ConfigureServices方法:

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

此选项用于配置方法:

app.UseCors("DevCorsPolicy");
戚峻
2023-03-14

@Dmitriy Grebennikov的答案也是正确的,但它需要一些改进以使其更加安全。

Startup.cs的ConfigureServices中,在services.AddControllers()之前添加以下代码

services.AddCors(options =>
            {
                options.AddDefaultPolicy(builder => 
                builder.WithOrigins("https://localhost:44338")
                       .AllowAnyMethod()
                       .AllowAnyHeader());
            }); 

确保您的url不应以/结尾。

您可以通过origins方法将许多url传递给。最后,在Startup.cs的Configure方法中,在app.UseAuthorization()之前添加以下行 和之后app.UseRouting()

app.UseCors();

代码现在应该可以工作了。

 类似资料:
  • 我有一个使用RESTEasy的简单客户端,如下所示: 服务器配置为在以及一条有用的信息。正在抛出一个。除了包装在中之外,我如何使捕获异常并以字符串形式返回响应的有用消息。我尝试了各种实现,但似乎都是正确的。上述代码从未调用。我错过了什么? 我目前的解决方法是使用,然后执行并将原始状态填充到响应实体中。这样我就避免了异常抛出。

  • 我的项目是客户端/服务器,客户端发送一个对象到服务器,服务器响应,所有这些都是通过RMI 客户项目 //接口 //我需要把它发给的班级 //客户端 //服务器项目 //接口公共接口RMI_接口扩展了远程{ //类,我将发送和接收它公共类Employee实现可序列化的{int ID; //类来保存所有接收到的对象公共类Maneger{ //服务器公共类RMI_server扩展了UnicastRemo

  • 我正在使用Android异步Http客户端。我的代码看起来像这样,并且运行良好。 我实现了一个静态HTTP客户端。我的服务器返回这个JSON数据。我不想将其视为字符串并将其转换回JSON。但是当我将其更改为eclipse告诉我 new AsyncHttpResponseHandler(){}类型的onSuccess(JSONObject)方法必须重写或实现超类型方法

  • 为方便测试,我们以RPC中的例子来实现服务端,具体请看文档RPC章节。 纯原生异步 public static function mainServerCreate(ServerManager $server,EventRegister $register): void { // TODO: Implement mainServerCreate() method.

  • 我正在尝试将我的应用程序从apache http组件客户端切换到异步版本。目标是能够处理更多的出站连接(在不久的将来)。请求的负载非常小( 与同步版本的apache超文本传输协议客户端,通过把大约200请求/秒。平均响应时间约为100ms/请求。我在最大180ms后中止请求。 切换到异步后,响应时间增加了20ms/请求。吞吐量也降低到160/秒。中止的请求数量增加了一倍。 这是在对应用程序进行了很

  • 我有一个从服务器端抛出的异常,我希望在客户端捕捉到这个异常。异常应该使用Jersey通过REST发送。这是我目前所掌握的: 定义我的异常: