MobileBlazorBindings icon indicating copy to clipboard operation
MobileBlazorBindings copied to clipboard

NavigationManager does not work anymore on Hybrid Apps

Open Lele0037 opened this issue 2 years ago • 2 comments
trafficstars

A year ago (circa) I built an hybrid app using Mobile Blazor Bindings:

dotnet new blazorhybrid -o <my app>

Suddently (maybe due to a recent Google/Android update?) the NavigationManager seems not to be working anymore: my app simply does not navigate to the page it is supposed to go. In another words, the function

@inject NavigationManager navigationManager;

<button @onclick="Navigate">Navigate</button>

@code {
    private void Navigate () {
        navigationManager.NavigateTo("/my-page");
    }
}

does nothing at all. It does not even throw an exception. I noticed, tinkering with the chrome console while the app is running, that when I try to navigate using the javascript function underneath I received the following error:

[chromium] [INFO:CONSOLE(1)] "Uncaught  SecurityError: Failed to execute 'pushState' on 'History': A history state object with URL 'app://0.0.0.0/<my path>' cannot be created in a document with origin 'app://' and URL 'app://0.0.0.0/'.", source:            framework://blazor.desktop.js (1)

Could someone please help me? My app was working perfectly last week and now all the devices where the app is installed are failing one by one. My only guess is that something changed with the default Android Web View app (I noticed it has been updated recently).

Lele0037 avatar Sep 28 '23 13:09 Lele0037

Hi @Lele0037 , I'm not sure what could have caused this, but if you're looking to gain some new features as well as lots of bugs fixes, I recommend using this fork of Mobile Blazor Bindings by @Dreamescaper : https://github.com/Dreamescaper/BlazorBindings.Maui

Eilon avatar Oct 02 '23 16:10 Eilon

you can temporarily fix it by overriding navigateTo, by suppressing history recording, you can add it to index.html, something like that

<script>
        let testAnchor;

        var blazorLoading = setInterval(() => {
            if (window.Blazor) {
                clearInterval(blazorLoading);

                Blazor._internal.navigationManager.navigateTo = function (uri, forceLoad, replace) {
                    const absoluteUri = toAbsoluteUri(uri);
                    if (!forceLoad && isWithinBaseUriSpace(absoluteUri)) {
                        // It's an internal URL, so do client-side navigation
                        performInternalNavigation(absoluteUri, false, replace);
                    } else if (forceLoad && location.href === uri) {
                        // Force-loading the same URL you're already on requires special handling to avoid
                        // triggering browser-specific behavior issues.
                        // For details about what this fixes and why, see https://github.com/aspnet/AspNetCore/pull/10839
                        const temporaryUri = uri + '?';
                        location.replace(uri);
                    } else if (replace) {

                    } else {
                        // It's either an external URL, or forceLoad is requested, so do a full page load
                        location.href = uri;
                    }
                }
            }
        }, 5);

        function performInternalNavigation(absoluteInternalHref, interceptedLink, replace = false) {
            DotNet.invokeMethodAsync('Microsoft.MobileBlazorBindings.WebView', 'NotifyLocationChanged', absoluteInternalHref, interceptedLink)
        }

        function isWithinBaseUriSpace(href) {
            const baseUriWithTrailingSlash = toBaseUriWithTrailingSlash(document.baseURI); // TODO: Might baseURI really be null?
            return href.startsWith(baseUriWithTrailingSlash);
        }

        function toBaseUriWithTrailingSlash(baseUri) {
            return baseUri.substr(0, baseUri.lastIndexOf('/') + 1);
        }

        function toAbsoluteUri(relativeUri) {
            testAnchor = testAnchor || document.createElement('a');
            testAnchor.href = relativeUri;
            return testAnchor.href;
        }
    </script>

plamenkraev avatar Oct 03 '23 07:10 plamenkraev