Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

[iOS] WebView.Source URL's are HTML encoded in Xamarin.Forms 3.0.0.482510 #2736

Closed
jnsn opened this issue May 16, 2018 · 7 comments
Closed

Comments

@jnsn
Copy link

jnsn commented May 16, 2018

Description

When setting the WebView.Source property on iOS, the URL is encoded. On Android it is not. This did not happen in previous versions of Xamarin.Forms and is causing a massive issue when redirecting to an Identity Server which expects a valid formatted redirect uri, thus generating an error which prevents us from logging in into our application.

The attached sample demonstrates this problem by querying Google for the Microsoft website.

Steps to Reproduce

  1. Add a WebView control to a page.
  2. Set the source to a URL which contains already encoded data, for example: https://www.google.com/search?q=http%3A%2F%2Fmicrosoft.com

Expected Behavior

The WebView should not encode the URL.

Actual Behavior

The URL is encoded again, so the %3A is encoded to %253A. So the actual opened page is as follows:

  • Android: https://www.google.com/search?q=http%3A%2F%2Fmicrosoft.com
  • iOS: https://www.google.com/search?q=http%253A%252F%252Fmicrosoft.com

If you paste the URL's in your browser you can see the wanted behavior on Android, and the erroneous behavior on iOS.

Basic Information

  • Version with issue: 3.0.0.482510
  • Last known good version: 2.5.1.444934
  • IDE: Visual Studio 2017 15.7.1
  • Platform Target Frameworks:
    • iOS: 11.3
    • Android: 8.1

Screenshots

Android:
image

iOS:
image

Reproduction Link

Bug.WebUriDoubleEncoding.zip

@pauldipietro pauldipietro added this to New in Triage May 16, 2018
@StephaneDelcroix StephaneDelcroix added this to Ready in v3.0.0 via automation May 16, 2018
@StephaneDelcroix StephaneDelcroix removed this from New in Triage May 16, 2018
@StephaneDelcroix StephaneDelcroix added this to the 3.0.0 milestone May 16, 2018
@StephaneDelcroix
Copy link
Member

/cc @samhouts

@jnsn
Copy link
Author

jnsn commented May 16, 2018

I believe the issue is caused by 14aa258#diff-1f852655bc37c1648eb2589cb1398b20R82 where the URL encoding was added for iOS devices.

@bholmes bholmes removed the 3.0.0 label May 22, 2018
@PureWeen
Copy link
Contributor

possible fix
https://stackoverflow.com/questions/36685160/unicode-url-could-not-initialize-an-instance-of-the-type-foundation-nsurl-t

@paleicikas
Copy link

The same (CRITICAL) problem with FormUrlEncodedContent (iOS only; previously worked well):

var p = new List>
{
    new KeyValuePair("a", "b"),
    new KeyValuePair("c", "https://www.google.com/search?source=hp&ei=x&q=trolo+boli&oq=trolo+boli")
};

var c = new FormUrlEncodedContent(p);

var q = c.ReadAsStringAsync().Result;
System.Diagnostics.Debug.WriteLine("var q = " + q);

var b = new UriBuilder("example.com")
{
    Query = q
};

System.Diagnostics.Debug.WriteLine("var b = " + b);

Debug:

var q = a=b&c=https%3A%2F%2Fwww.google.com%2Fsearch%3Fsource%3Dhp%26ei%3Dx%26q%3Dtrolo%2Bboli%26oq%3Dtrolo%2Bboli
var b = http://example.com:80/?a=b&c=https%3A%2F%2Fwww.google.com%2Fsearch%3Fsource%3Dhp%26ei%3Dx%26q%3Dtrolo%2Bboli%26oq%3Dtrolo%2Bboli

@paleicikas
Copy link

Even more (iOS only, previously worked well):

var webview = new WebView { 
 ... URL: 
};

webview.Navigating += async (sender, args) =>
{
    args.Url // will be twice url encoded, no way to use this property anymore 
}

LeoLiXX referenced this issue May 25, 2018
…acters (#2111)

* [Controls] Add reproduction for issue #1583

* [iOS] Encode url so it doesn't fail with non-ascii characters fixes #1583

* Update Issue1583_1.cs
@bart-256
Copy link

I've faced the same issue - loading mp4 videos from Azure using WebView suddenly stopped working on iOS after updating to XF 3.0. Couldn't downgrade, because I've used 3.0 new features everywhere in the app. I believe I've got working workaround for LoadUrl function issue referenced here: #2736 (comment)

Create custom control:

public class CustomWebView : WebView
{
}

Create renderer:

[assembly: ExportRenderer(typeof(MyProject.Core.CustomControls.CustomWebView), typeof(MyProject.iOS.CustomRenderers.CustomWebViewTerribleBugRenderer))]
namespace MyProject.iOS.CustomRenderers
{
    public class CustomWebViewTerribleBugRenderer : Xamarin.Forms.Platform.iOS.WebViewRenderer
    {
        public override void LoadRequest(NSUrlRequest r)
        {
            var stackTrace = new StackTrace();
            var stackFrames = stackTrace.GetFrames();

            // check if this was(n't) called from LoadUrl method, since we can't override it...
            if (!stackFrames.Any(x => x.GetMethod().Name == "LoadUrl" && x.GetMethod().DeclaringType == typeof(Xamarin.Forms.Platform.iOS.WebViewRenderer)))
            {
                // called from other place so just call base and return
                base.LoadRequest(r);
                return;
            }

            // reconstruct original URL
            var decodedStringUrl = new NSString(r.Url.AbsoluteString).CreateStringByReplacingPercentEscapes(NSStringEncoding.UTF8);

            // call load request with original string
            base.LoadRequest(new NSUrlRequest(new NSUrl(decodedStringUrl)));
        }
    }
}

Use it instead of normal WebView:

<cc:CustomWebView 
                HorizontalOptions="FillAndExpand"
                VerticalOptions="FillAndExpand"
                x:Name="webView"
                BackgroundColor="#0b0b0b" 
                Source="{Binding VideoSource}"
                Grid.Row="0" />

This is just workaround, it's a bit hacky but it works in my case. Tested on real device - Release.

bruzkovsky pushed a commit to bruzkovsky/Xamarin.Forms that referenced this issue May 29, 2018
@samhouts samhouts added this to In Progress in v3.6.0 May 29, 2018
@samhouts samhouts removed this from In Progress in v3.6.0 May 29, 2018
@samhouts samhouts moved this from Ready to In Progress in v3.0.0 May 29, 2018
bruzkovsky pushed a commit to bruzkovsky/Xamarin.Forms that referenced this issue May 30, 2018
@samhouts samhouts moved this from In Progress to Done in v3.0.0 Jun 7, 2018
@bbl-Laobu
Copy link

The current fix for iOS scrapes away any port passed along in the url.
url="http://192.168.0.33:5000/connect" is evaluated as http://192.168.0.33/connect

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
No open projects
v3.0.0
  
Done
Development

No branches or pull requests

7 participants