unoplatform / uno

Open-source platform for building cross-platform native Mobile, Web, Desktop and Embedded apps quickly. Create rich, C#/XAML, single-codebase apps from any IDE. Hot Reload included! 90m+ NuGet Downloads!!
https://platform.uno
Apache License 2.0
9.07k stars 735 forks source link

Basic stuff: HttpClient not working in WebAssembly App #18912

Closed hbraasch closed 2 days ago

hbraasch commented 4 days ago

Current behavior

I'm a newbie to Uno, thinking to migrate away from .net MAUI. But I quickly ran into this basic problem:

Using a VERY simple app, you click a button and then access www.google.com using HttpClient. It works when compiled for Android, it fails when compiled for WebAssembly.

The sample repository is here: https://github.com/hbraasch/UnoHttpClientTester.git

The HttpClient code used is here:

private async void MyButton_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
    try
    {
        using (var client = new HttpClient())
        {
            HttpResponseMessage response = await client.GetAsync("https://www.google.com");
            if (response.IsSuccessStatusCode)
            {
                string responseData = await response.Content.ReadAsStringAsync();
                statusBox.Text = string.IsNullOrEmpty(responseData)? "No data back": "Got data back";
            }
            else
            {
                statusBox.Text = "Error: " + response.StatusCode;
            }
        }
    }
    catch (Exception ex)
    {
        statusBox.Text = ex.Message;
    }
}

This is the result when running Android:

image

This is the result when running WebAssembly:

image

Anu idea what can be wrong?

Help shall be much appreciated.

Expected behavior

The WebAssembly App must respond exactly the same as Android App

How to reproduce it (as minimally and precisely as possible)

Minimal repro project supplied:

https://github.com/hbraasch/UnoHttpClientTester.git

Workaround

Not known

Works on UWP/WinUI

Yes

Environment

No response

NuGet package version(s)

Nothing extra used

Affected platforms

WebAssembly

IDE

Visual Studio 2022

IDE version

N/A

Relevant plugins

N/A

Anything else we need to know?

Have no idea how to fix this

MartinZikmund commented 4 days ago

It may likely be a CORS issue (https://en.wikipedia.org/wiki/Cross-origin_resource_sharing), HttpClient requests are bound by security considerations of the browser, so if the target (in this case Google) does not have permissive CORS, you will not be able to make such API request. This is easy to solve for APIs you control (you can just adjust CORS so that your WASM app's URI is allowed), or many APIs (including Google APIs) allow you to register your app and fill out your app's URI so that you can access them.

hbraasch commented 3 days ago

Thank you! You're right. I've now added CORS to "a server I control", and it now works fine.

I've just came across a curiosity, if I instantiate a HttpClient in the following way (with a handler that accepts all certificates), it fails with an [Operation not supported on this platform] when doing client.Get() or client.Post(). It still works for Android and Desktop.

Here is the code that exposes it:

            HttpClientHandler handler = new HttpClientHandler();

            //not sure about this one, but I think it should work to allow all certificates:
            handler.ServerCertificateCustomValidationCallback += (sender, cert, chaun, ssPolicyError) =>
            {
                return true;
            };

            var client = new HttpClient(handler, false);

Do you think its an intentional feature, or should I raise it as an issue?

Regards

jeromelaban commented 2 days ago

I've just came across a curiosity, if I instantiate a HttpClient in the following way (with a handler that accepts all certificates), it fails with an [Operation not supported on this platform] when doing client.Get() or client.Post(). It still works for Android and Desktop.

This an intentional feature, yes, coming from the .NET runtime. The underlying fetch API cannot provide that feature, and it's been disabled in the BCL.