Search code examples
c#blazorcorsblazor-webassemblywebassembly

Blazor HttpClient stuck in GetAsync


I'm making test in a Client Side Blazor app targeting Blazor 3.0.0-preview4-19216-03

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.

UPDATE

If I debug the service WebCrawler in Chrome's WASM debugger, he request is being made

enter image description here

But the response section is empty:

enter image description here


Solution

  • From a client-side app you can only acces your own origin or sites that support 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.

    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. The same goes for any app on JS or WASM.

    Blazor server-side should have no problems. Or use a Web API service.


    You can try this in a Wasm app:

    @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");
        }
    }