Skip to content
This repository has been archived by the owner on Dec 17, 2021. It is now read-only.

[Bug] href=javascript:void(0) opens the browser on android #185

Open
arivera12 opened this issue Mar 24, 2020 · 18 comments
Open

[Bug] href=javascript:void(0) opens the browser on android #185

arivera12 opened this issue Mar 24, 2020 · 18 comments
Assignees

Comments

@arivera12
Copy link

When there is a link like this
<a href="javascript:void(0)">Link</a>
The blazor app opens the browser.

I haven't tested ios and windows phone to check if this behavior occurs cause I don't have those device to test them out.

@arivera12 arivera12 changed the title href=javascript:void(0) opens the browser on android [bug] href=javascript:void(0) opens the browser on android Mar 24, 2020
@arivera12 arivera12 changed the title [bug] href=javascript:void(0) opens the browser on android [Bug] href=javascript:void(0) opens the browser on android Mar 24, 2020
@Daddoon
Copy link
Owner

Daddoon commented Mar 24, 2020

Read this documentation :

https://github.com/Daddoon/BlazorMobile#validating-the-blazor-application-navigation

Maybe I will remove the default code I made in template as people always ask without reading.

But I agree, this behavior on JavaScript is surely a side effect with GeckView Navigation event on Android even if it’s not a real full navigation.

@Daddoon Daddoon closed this as completed Mar 24, 2020
@arivera12
Copy link
Author

arivera12 commented Mar 24, 2020

@Daddoon

I ended adding this condition and works perfectly.

if (e.Url.StartsWith("javascript:void", StringComparison.OrdinalIgnoreCase))
{
     e.Cancel = true;
}

Why you just don't add this condition on the OnBlazorWebViewNavigating.

I think it's pretty obvious when we add javascript:void or javascript:void(0) on a href we don't want the browser to do anything.

@arivera12
Copy link
Author

Read this documentation :

https://github.com/Daddoon/BlazorMobile#validating-the-blazor-application-navigation

Maybe I will remove the default code I made in template as people always ask without reading.

But I agree, this behavior on JavaScript is surely a side effect with GeckView Navigation event on Android even if it’s not a real full navigation.

I think the default code is ok.

If something its a different from base address of the application it should open the browser.

That behavior is ok for most cases.

But when href is javascript:void it should not do anything.

@Daddoon
Copy link
Owner

Daddoon commented Mar 24, 2020

I agree with you.

Maybe i will add some kind of workaround for Android for this case at low level.
Actually only this platform may fire this, it doesn't use the same mecanism for forwarding request events, that's why there is a WebExtension loaded on Android (and also why there is a BlazorMobile.Build.Android NuGet package !) .

There is a WebExtension loaded with the GeckoView engine by myself, that listen to onBeforeRequest events and forward them a the BlazorMobile webserver in order to receive the navigation validation logic from Native.

The only problem is as your issue here: It seem that Mozilla WebExtensions has strange (in my opinion) side effects, like javascript void firing this event, or even the javascript history navigation engine (even if the page is not reloaded), there is an issue already opened for this i will try to figure one day.

Maybe there is other edge case i don't know yet.

@arivera12
Copy link
Author

I am testing hash -> # with href to see if navigates to specific content and doesn't navigate.

I add a href="#test" and element with id="test" and doesn't work.

@Daddoon
Copy link
Owner

Daddoon commented Mar 24, 2020

I'm not sure the hash thing work on Blazor generally.

Were you expecting a Navigation event on Android ? As far as i know, this is not always considered as a navigation.

Do you have a different behavior if you test your code from an external browser with remote debugging ?

@arivera12
Copy link
Author

Yes I am on android.

@arivera12
Copy link
Author

haven't test browser 1 min

@arivera12
Copy link
Author

same behavior on browser doesn't navigate to content.

@Daddoon
Copy link
Owner

Daddoon commented Mar 24, 2020

If it doesn't work externally too, it's not related to BlazorMobile but maybe on Blazor generally speaking.

@arivera12
Copy link
Author

haven't try on blazor. Let me create a blazor fiddle and test it out.

@arivera12
Copy link
Author

arivera12 commented Mar 24, 2020

I created a fresh simple blazor fiddle to test hash navigation and doesn't work on blazor. Blazor just behaves like that.
https://blazorfiddle.com/s/35gc9a26

There should be a work around for that but is ok by your side.

@arivera12
Copy link
Author

I agree with you.

Maybe i will add some kind of workaround for Android for this case at low level.
Actually only this platform may fire this, it doesn't use the same mecanism for forwarding request events, that's why there is a WebExtension loaded on Android (and also why there is a BlazorMobile.Build.Android NuGet package !) .

There is a WebExtension loaded with the GeckoView engine by myself, that listen to onBeforeRequest events and forward them a the BlazorMobile webserver in order to receive the navigation validation logic from Native.

The only problem is as your issue here: It seem that Mozilla WebExtensions has strange (in my opinion) side effects, like javascript void firing this event, or even the javascript history navigation engine (even if the page is not reloaded), there is an issue already opened for this i will try to figure one day.

Maybe there is other edge case i don't know yet.

ohh I see but its still very strange behavior. There should be a easy quick fix for this internally on GeckoView engine for other cases. In the meantime my condition worked perfectly.

@Daddoon
Copy link
Owner

Daddoon commented Mar 27, 2020

I added an additional condition in the controller managing how requests validation are managed by the end user on Android.

All request starting with javascript: should be ignored (not transfered to the Navigation validator) and considered as a cancelled navigation.

This mean that in the next version shipped, you should not have to manage by yourself anymore javascript: requests, as they will not be forwarded.

Snippet of code in the BlazorController that validate the behavior (just for info):

        private bool ShouldExcludeFromNavigatingEvent(string uri, out bool shouldCancel)
        {
            shouldCancel = false;

            if (!string.IsNullOrEmpty(uri))
            {
                if (uri.StartsWith("javascript:", StringComparison.OrdinalIgnoreCase))
                {
                    shouldCancel = true;
                    return true;
                }
            }

            return false;
        }

        private async Task<bool> ValidateRequestAndroid(string webextensionId)
        {
            string cancel = "false";

            if (int.TryParse(webextensionId, out int runtimeId))
            {
                var webview = WebViewHelper.GetWebViewByRuntimeIdentity(runtimeId);
                if (webview != null)
                {
                    string uri = this.Request.QueryString.Get("uri");
                    string referrer = this.Request.QueryString.Get("referrer");

                    if (ShouldExcludeFromNavigatingEvent(uri, out bool shouldCancel))
                    {
                        if (shouldCancel)
                        {
                            cancel = "true";
                        }
                    }
                    else
                    {
                        var args = new WebNavigatingEventArgs(
                        WebNavigationEvent.NewPage,
                        new UrlWebViewSource() { Url = referrer },
                        uri);

                        webview.SendNavigating(args);

                        if (args.Cancel)
                        {
                            cancel = "true";
                        }
                    }
                }
            }

            IWebResponse response = new EmbedIOWebResponse(this.Request, this.Response);
            response.SetEncoding("UTF-8");
            response.AddResponseHeader("Cache-Control", "no-cache");
            response.SetStatutCode(200);
            response.SetReasonPhrase("OK");
            response.SetMimeType("text/plain");
            await response.SetDataAsync(new MemoryStream(Encoding.UTF8.GetBytes(cancel)));
            return true;
        }

@arivera12
Copy link
Author

Nice! keep up the good work! I will have this in consideration,

@arivera12
Copy link
Author

arivera12 commented Mar 28, 2020

Is this shipped in 3.2.4? Is yes I commented my code and android opens the browser again.

@Daddoon
Copy link
Owner

Daddoon commented Mar 28, 2020

Yes it should.

However I didn’t test as it seemed simple. I will check that in the future, it’s not blocking.

@Daddoon Daddoon reopened this Mar 28, 2020
@Daddoon Daddoon self-assigned this Mar 28, 2020
@Daddoon Daddoon added this to the BlazorMobile 3.2.5-x milestone Mar 28, 2020
@arivera12
Copy link
Author

I know, it was so simple that didn't need test hahahaha but didn't work at all.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants