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.
https://www.google.com/search?q=http%3A%2F%2Fmicrosoft.com
The WebView should not encode the URL.
The URL is encoded again, so the %3A
is encoded to %253A
. So the actual opened page is as follows:
https://www.google.com/search?q=http%3A%2F%2Fmicrosoft.com
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.
Android:
iOS:
/cc @samhouts
I believe the issue is caused by https://github.com/xamarin/Xamarin.Forms/commit/14aa258915842caf292e61bde005889e98cd410b#diff-1f852655bc37c1648eb2589cb1398b20R82 where the URL encoding was added for iOS devices.
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
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 }
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: https://github.com/xamarin/Xamarin.Forms/issues/2736#issuecomment-389443737
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.
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
Most helpful comment
I believe the issue is caused by https://github.com/xamarin/Xamarin.Forms/commit/14aa258915842caf292e61bde005889e98cd410b#diff-1f852655bc37c1648eb2589cb1398b20R82 where the URL encoding was added for iOS devices.