dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
22.06k stars 1.73k forks source link

[MacCatalyst] IFrame to external URL opens in external browser, despite mitigation strategies [Blazor Hybrid] #23429

Open caliberdigitalllc opened 3 months ago

caliberdigitalllc commented 3 months ago

Description

I have a maui app that I am deploying on windows, iOS and MacCatalyst.

On windows, for the most part, my iframe page works good, but usually on iOS and mac, external urls load in the external browser, which is not the intended behavior.

I've created a component called "UrlViewer". When I navigate here, the external url should load in the iframe, not in safari or some other external browser.

@page "/UrlViewer"

<SpinnerOverlay />

<div class="iframe-container">
    <button @onclick="GoBack">Back</button>
    <iframe id="contentFrame" src="@iframeUrl" class="iframe-content"></iframe>
</div>

public partial class UrlViewer {
    [SupplyParameterFromQuery]
    public string url { get; set; }

    [SupplyParameterFromQuery]
    public string returnPage { get; set; }
    public string iframeUrl { get; set; }

    protected override void OnInitialized() {
        iframeUrl = url;
    }

    protected override async Task OnAfterRenderAsync(bool firstRender) {
        if (firstRender) {
            await _jSRuntime.InvokeVoidAsync("showSpinner");
        }
    }

    private void GoBack() {
        _navManager.NavigateTo($"/{returnPage}");
    }
}

Steps to Reproduce

Per some guidance I found on the internet, I created this url loading policy:

public class UrlLoadingPolicy {
    private static readonly HashSet<string> AllowedUrls = new HashSet<string> {
    "https://alzbetter.us",
    "https://static.alzbetter.net"
};

    public bool ShouldLoadUrlInWebView(string url) {
        return AllowedUrls.Contains(url);
    }
}

Then over in MainPage:

public partial class MainPage : ContentPage {
    public MainPage() {
        InitializeComponent();
        blazorWebView.UrlLoading += BlazorWebView_UrlLoading;
    }

    private void BlazorWebView_UrlLoading(object sender, UrlLoadingEventArgs e) {
        var policy = new UrlLoadingPolicy();
        e.UrlLoadingStrategy = UrlLoadingStrategy.OpenInWebView;

        if (policy.ShouldLoadUrlInWebView(e.Url.ToString())) {
            e.UrlLoadingStrategy = UrlLoadingStrategy.OpenInWebView;
        } else {
            e.UrlLoadingStrategy = UrlLoadingStrategy.OpenExternally;
        }
    }
}

Is there a better way to handle this situation, or something more up to date in terms of an approach?

Link to public reproduction project repository

No response

Version with bug

9.0.0-preview.4.10690

Is this a regression from previous behavior?

No, this is something new

Last version that worked well

Unknown/Other

Affected platforms

iOS, macOS

Affected platform versions

No response

Did you find any workaround?

No response

Relevant log output

No response

github-actions[bot] commented 3 months ago

Hi I'm an AI powered bot that finds similar issues based off the issue title.

Please view the issues below to see if they solve your problem, and if the issue describes your problem please consider closing this one and thumbs upping the other issue to help us prioritize it. Thank you!

Open similar issues:

Closed similar issues:

Note: You can give me feedback by thumbs upping or thumbs downing this comment.

RoiChen001 commented 3 months ago

I can repro this issue at iOS and MacCatalyst platform on the latest 17.16.12 (build 410)(8.0.70 & 9.0.0-preview.6.24327.7).