This could seem to be duplicates of other similar questions but they are old thread and not specific to Windows UWP apps.
I'm unable to set custom header in WebView so the loaded URLs in WebView could work for me.
I have seen many forums giving solution like using HttpClient/WebRequest with header but that doesn't work as in my case, the web address usage Javascript for redirection and before redirection it needs few custom header to load correctly.
Also WebView.NavigateWithHttpRequestMessage is not so suitable as it will postback and I need the headers for each request including javascript redirected URLs in web View.
I'm able to set custom headers in Xamarin.Droid project using Renderers but I couldn't find any solution for UWP Windows.UI.Xaml.Controls.WebView.
On Universal Windows 10 Platform, the WebView.NavigateWithHttpRequestMessage method is the right way.
a. I need the headers for each request including javascript redirected URLs in web View.
b. This didn't resolve my issue as after setting the headers the OnWebViewNavigationStarting method is called multiple times and App crashes automatically with System.StackOverflowException error
This is due to the infinite navigation will happen if we do navigation in the NavigationStarting event. We should cancel navigation in a handler for this event by setting the WebViewNavigationStartingEventArgs.Cancel property to true.
And we need to add/remove handler for NavigationStarting event carefully.
Code sample:
private void NavigateWithHeader(Uri uri)
{
var requestMsg = new Windows.Web.Http.HttpRequestMessage(HttpMethod.Get, uri);
requestMsg.Headers.Add("User-Name", "Franklin Chen");
wb.NavigateWithHttpRequestMessage(requestMsg);
wb.NavigationStarting += Wb_NavigationStarting;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
NavigateWithHeader(new Uri("http://openszone.com/RedirectPage.html"));
}
private void Wb_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args)
{
wb.NavigationStarting -= Wb_NavigationStarting;
args.Cancel = true;//cancel navigation in a handler for this event by setting the WebViewNavigationStartingEventArgs.Cancel property to true
NavigateWithHeader(args.Uri);
}
The screenshot is the log info in Fiddler, the request record in the second red rectangle included the custom header:
I shared my UWP sample in here, you can easily integrate into your Xamarin UWP app.
With the Xamarin Tag, it seems like you are using this with Xamarin.Forms and hence the below answer is with respect to Xamarin.Forms.
However, the code holds true for WebView in UWP as well.
You can try creating a Custom Renderer for WebView and then try making use of the same WebView.NavigateWithHttpRequestMessage.
Before navigating you can try setting the Headers like this:
var requestMsg = new Windows.Web.Http.HttpRequestMessage(HttpMethod.Get, new Uri("https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending"));
requestMsg.Headers.Add("User-Name", "AnubhavRanjan");
Control.NavigateWithHttpRequestMessage(requestMsg);
The Uri above can be set based on your requirement.
In case the request is happening multiple times, you can always set the delegate for NavigationStarting event and handle it in the method.
Control.NavigationStarting += OnWebViewNavigationStarting
Related
I get the application selection popup when I'm loading some customer webcontent into my webview, I guess its calling and uri with an unknown protocol or something. I don't care about the contents, I just want to react before the popup appears.
I tried the following but I won't get called by
webView.NavigationStarting += WebView_NavigationStarting;
webView.ScriptNotify += WebView_ScriptNotify;
They are only called when expected, but not before the popup.
Is there another event I can subscribe to, so I can handle it and decide if it is necessary to show the popup or just flag it as handled?
I get the application selection popup when I'm loading some customer webcontent into my webview.
The screenshot in your case is the window of openwith.exe system level app. It will be launched by unknown application uri(Name:Parameter) scheme. It will not invoke NavigationStarting and ScriptNotify event. For more you could refer to Handle URI activation.
Is there another event I can subscribe to, so I can handle it and decide if it is necessary to show the popup or just flag it as handled?
Currently, there is no such event for detecting the popup.
For your requirement, you can filter the special uri scheme in the html page manually.
For more, you could refer to Launch the default app for a URI. And create appropriate filter based on these uri scheme.
Example
function myFunction() {
var url = "test:paramter"
var arr = url.split(":");
if (arr[0] == "test") {
arr[0] = "";
}
var url = arr.join('');
}
Scenario
I am creating a simple embedded "browser" for my app, which opens in a Popup, when the user clicks on a button with a hyperlink designed to open "in-app".
The popup is opened, and the (simply-named) WebView is navigated to the URL specified in the hyperlink.
There are the typical Back, Forward and Refresh/Stop buttons that are enabled/disabled accordingly.
Current Situation
I have wired up the necessary events for NavigationStarted, NavigationCompleted and others for Falied, Loaded etc. etc.
These are performed along with some "naughty" ViewModel wiring when the UserControl is loaded TL;DR - there is no way I can find to keep to MVVM practice with WebViews, what a PITA!:
private void OnLoaded(object sender, RoutedEventArgs e)
{
if (this.DataContext is IWebViewUserControlViewModel)
{
this.WebView.ContentLoading += OnWebViewContentLoading;
this.WebView.DOMContentLoaded += OnWebViewDomContentLoaded;
this.WebView.NavigationStarting += OnWebViewNavigationStarting;
this.WebView.NavigationCompleted += OnWebViewNavigationCompleted;
this.WebView.UnviewableContentIdentified += OnWebViewUnviewableContentIdentified;
this.WebView.NavigationFailed += OnWebViewNavigationFailed;
this.viewModel = DataContext as IWebViewUserControlViewModel;
NavigateToUrl(this.viewModel?.Url);
}
}
This is so that I navigate to the URL when the UserControl is loaded, and can evaluate the button states as the user navigates around using the events above.
The NavigateToUrl() method just contains a try/catch block to counteract any errors forming the Uri etc.:
private void NavigateToUrl(string url)
{
try
{
var uri = new Uri(url);
this.WebView.Navigate(uri);
}
catch (Exception ex)
{
this.WebView.NavigateToString($"An error occurred: {ex.Message}")
}
}
Back/Forward UX
In particular the Back and Forward buttons are disabled/enabled when navigation to a page is started/completed respectively.
I evaluate their IsEnabled states like so:
btnBackButton.IsEnabled = this.WebView.CanGoBack;
btnForwardButton.IsEnabled = this.WebView.CanGoForward;
This works fine throughout the entire time that the user is browsing.
The Issue
Should the user close the popup, and re-open it via the same or a different link, the correct URL is navigated to - all good.
The issue is, that their previous browsing session was never cleared from the MyWebView, and thus the btnBackButton (not the forward, as this the latest navigation in the history stack) is now enabled again - allowing them to traverse their previously visited pages.
I don't want this behaviour.
I would like it to appear that their session is a "new", fresh one - without the Back button enabled - as if it had just been opened.
What I have already tried...
I am unable to manually set the MyWebView.CanGoBack/MyWebView.CanGoForward properties to false when the popup is (re)opened.
They are get-only properties, so this is not possible.
I have tried re-initializing the WebView control when the containing UserControl is Loaded (in the same OnLoaded delegate as above):
private void OnLoaded(object sender, RoutedEventArgs e)
{
if (this.DataContext is IWebViewUserControlViewModel)
{
// Re-initialize the WebView
this.WebView = new WebView();
// Detect when the new control has loaded, and then wire up events/navigate as normal
this.WebView.Loaded += (sender, e) =>
{
this.WebView.ContentLoading += OnWebViewContentLoading;
this.WebView.DOMContentLoaded += OnWebViewDomContentLoaded;
this.WebView.NavigationStarting += OnWebViewNavigationStarting;
this.WebView.NavigationCompleted += OnWebViewNavigationCompleted;
this.WebView.UnviewableContentIdentified += OnWebViewUnviewableContentIdentified;
this.WebView.NavigationFailed += OnWebViewNavigationFailed;
this.viewModel = DataContext as IWebViewUserControlViewModel;
NavigateToUrl(this.viewModel?.Url);
}
}
}
In the hope that this might work - but the Loaded delegate of the WebView is never fired.
In the UI, the WebView just doesn't appear.
Help!?
Is there any way for me to clear the navigation history for the WebView control, so it appears that the browsing session is a "new" one?
Your help is appreciated, as always. Many thanks.
If your app is Windows 8.1, actually there is no programmatic way to clear the webview cache according to what #MattĀ said in thisĀ link(part 7).
And if it is a UWP app, please refer to this doc.
When navigating using the webview in a Windows Store app any links which try to open in a new tab/windows or opened in internet explorer thus practically pulling users from my app. is there any way to handle the link event to either force the links to open in current view or a way to run code to create a new tab within my own app. i have had a look around and can't seem to see much in the way of a defined way of doing this.
You can hook up to the WebViews "NavigationStarting" event.
The you can cancel the navigation and reissue it from within your code so it navigates inside the webview.
Xaml:
<WebView NavigationStarting="WebView_NavigationStarting" />
Codebehind:
private void WebView_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args)
{
if (args.Uri != null)
{
args.Cancel = true;
sender.Navigate(args.Uri);
}
}
But you will loose the ability to open links in new windows completely, as you only have the uri itself available in the event handler.
Uri will be null if you use the NavigateToString operations on the webview.
I have a C# WinRT app that uses the WebView control. None of the events I have created event handlers for are firing:
Uri theUri = new Uri("http://bing.com/");
webViewVideoPlayer.NavigationStarting += webViewVideoPlayer_NavigationStarting;
webViewVideoPlayer.NavigationCompleted += webViewVideoPlayer_NavigationCompleted;
webViewVideoPlayer.ContentLoading += webViewVideoPlayer_ContentLoading;
webViewVideoPlayer.NavigationFailed += webViewVideoPlayer_NavigationFailed;
webBrowserVideoPlayer.Navigate(theUri);
I have set breakpoints on the first line in each of the event handler bodies. The web page renders fine, but none of the breakpoints are hit. What can I do to fix this?
The app is currently configured for Debug build, x86 platform.
[TO THE MODERATORS: This is not my best post obviously. I was tired and made a silly mistake. If you feel it is best to delete it, please do.]
You've got two different control names in your code. The events are attached to webViewVideoPlayer, yet later the Navigate is called on a different WebView called webBrowserVideoPlayer.
I did a test with a WebView and the events were called as expected.
I have added a WebBrowser control on a page. If the user taps on any link in the WebBrowser I need to get the Uri of the request and load it in a new page. Im using WebBrowser class's Navigating event to get the url that is requested. To achieve what I need to do, I need to differentiate whether the navigation happens because of a link is clicked or by calling Navigate method or any redirection has happened. In iOS UIWebViewDelegate's shouldStartLoadWithRequest method passes UINavigation type as one of the arguments. This argument says whether the link is clicked or something else has happened like initial load or some redirection. How to find out this in WP8 WebBrowser control ?.
As mztan said there is no inbuilt way to detect the url click on a WebBrowser control in Windows phone 8.
Set a Navigating event to the WebBrowser and NavigatingEventArgs(argument) gives you the uri which have to be converted to string.Check the below Code.
private void webBrowser1_Navigating(object sender, NavigatingEventArgs e)
{
string val = e.Uri.ToString();
}