简体   繁体   English

Blazor HttpClient 卡在 GetAsync 中

[英]Blazor HttpClient stuck in GetAsync

I'm making test in a Client Side Blazor app targeting Blazor 3.0.0-preview4-19216-03我正在针对 Blazor 3.0.0-preview4-19216-03 的客户端 Blazor 应用程序进行测试

The razor page:剃须刀页面:

@page "/counter"
@using BlazorServiceTest
@inject IWebCrawlServiceAsync WebCrawler

<h1>Counter</h1>

<p>Current count: @debug</p>

<button class="btn btn-primary" onclick="@IncrementCount">Click me</button>

@functions {
    string debug = "";

    async void IncrementCount()
    {
        debug = await WebCrawler.GetWeb();
    }
}

The dependency injection:依赖注入:

using BlazorServiceTest;
using Microsoft.AspNetCore.Components.Builder;
using Microsoft.Extensions.DependencyInjection;

namespace BlazorServicesTest
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {   
            services.AddSingleton<IWebCrawlServiceAsync, WebCrawlServiceAsync>();            
        }

        public void Configure(IComponentsApplicationBuilder app)
        {
            app.AddComponent<App>("app");
        }
    }
}

The Service:服务:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;

namespace BlazorServiceTest
{
    public interface IWebCrawlServiceAsync
    {
        Task<string> GetWeb();
    }

    public class WebCrawlServiceAsync : IWebCrawlServiceAsync
    {
        private HttpClient _client;    

        public WebCrawlServiceAsync(HttpClient client)
        {
            _client = client;
        }

        public async Task<string> GetWeb()
        {
            var response = await _client.GetAsync("https://postman-echo.com/response-headers?foo1=bar1&foo2=bar2");
            var result = await response.Content.ReadAsStringAsync();
            return result;
        }
    }
}

Whenever I click in Increment count nothing happens and the service call to GetWeb it's stuck in the GetAsync call.每当我单击 Increment count 时,什么也没有发生,并且对GetWeb的服务调用卡在GetAsync调用中。

UPDATE更新

If I debug the service WebCrawler in Chrome's WASM debugger, he request is being made如果我在 Chrome 的 WASM 调试器中调试服务 WebCrawler,他会发出请求

在此处输入图片说明

But the response section is empty:但是响应部分是空的:

在此处输入图片说明

I suspect it has something to do with the async void .我怀疑它与async void

You need to have the handler return a Task , not void您需要让处理程序返回一个Task ,而不是void

For example例如

@page "/counter"
@using BlazorServiceTest
@inject IWebCrawlServiceAsync WebCrawler

<h1>Counter</h1>

<p>Current count: @debug</p>

<button class="btn btn-primary" onclick="@IncrementCount">Click me</button>

@functions {
    string debug { get; set; } = "";

    async Task IncrementCount() { //<-- Note Change here
        debug = await WebCrawler.GetWeb();
    }
}

support for async event handler is available in the framework框架中提供了对异步事件处理程序的支持

Reference GitHub Issue: Calling an async function via onclick参考GitHub 问题:通过 onclick 调用异步函数

This may be due to a CORS configuration issue on the server of which you have no control.这可能是由于您无法控制的服务器上的 CORS 配置问题。 I believe that this issue has nothing to do with Blazor.我认为这个问题与 Blazor 无关。 To verify this, define a local json file in your app and access it with the same code you use in your application.要验证这一点,请在您的应用程序中定义一个本地 json 文件,并使用您在应用程序中使用的相同代码访问它。

Hope this works...希望这有效...

UPDATE更新

I'm not entirely sure that the request fails due to CORS configuration issue, at least not exclusively.我不完全确定请求失败是由于 CORS 配置问题,至少不是唯一的。 It seems to me that it is also related to SSL/TLS.在我看来,它也与 SSL/TLS 相关。 This error message was issued by Fiddler:此错误消息由 Fiddler 发出:

fiddler.network.https> HTTPS handshake to failed. fiddler.network.https> HTTPS 握手失败。 System.IO.IOException Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. System.IO.IOException 无法从传输连接读取数据:远程主机强制关闭现有连接。 < An existing connection was forcibly closed by the remote host < 现有连接被远程主机强行关闭

The underlying connection is closed and no trust relationship can be established for the SSL/TLS secure channel.底层连接关闭,无法建立 SSL/TLS 安全通道的信任关系。

I guess I'll post this question in github to get a better understanding of what went wrong here.我想我会在 github 上发布这个问题,以便更好地了解这里出了什么问题。

From a client-side app you can only acces your own origin or sites that support CORS.从客户端应用程序,您只能访问您自己的源或支持 CORS 的站点。

In order to verify that this is your issue, you can try https://postman-echo.com/response-headers?foo1=bar1&access-control-allow-origin=* , that might work.为了验证这是您的问题,您可以尝试https://postman-echo.com/response-headers?foo1=bar1&access-control-allow-origin=* ,这可能有效。

But it will only work for that site.但它只适用于该网站。 You normally have no control over the response headers.您通常无法控制响应标头。 It's not a fix.这不是修复。

So, Blazor client-side is just not a good platform for a webcrawler.因此,Blazor 客户端对于网络爬虫来说并不是一个好的平台。 The same goes for any app on JS or WASM. JS 或 WASM 上的任何应用程序也是如此。

Blazor server-side should have no problems. Blazor 服务器端应该没有问题。 Or use a Web API service.或者使用 Web API 服务。


You can try this in a Wasm app:您可以在 Wasm 应用程序中尝试此操作:

@page "/"
@inject HttpClient Http

<h1>Hello, world!</h1>
<div>
    <button class="btn btn-primary" @onclick="GetData1">With CORS</button>
    <button class="btn btn-primary" @onclick="GetData2">No CORS</button>
</div>
<div>@json</div>

@code
{
    string json = ".";

    async Task GetData1()
    {        
        json = await Http.GetStringAsync(
         "https://postman-echo.com/response-headers" + 
         "?foo1=bar1&access-control-allow-origin=*");
    }

    async Task GetData2()
    {
        json = "Getting w/o CORS... ";
        json = await Http.GetStringAsync(
          "https://postman-echo.com/response-headers?foo1=bar1");
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM