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.
Related
Im building a WPF app and i'm trying to check several URL's in the background within a WebView2 window
Altough some urls have popups (which aren't real popups) in the upper left corner like asking for permission to use e.g. the microphone or something.
These popups are getting displayed in full size even if the visibility of the 1x1 pixel big webview is hidden
Here is an example of such a popup in my app:
The black corner is the edge of the app and as you can see the meet.google.com popup is displayed in full size even if the webview is invisible
I already tried to disable the notifications with the new window requested event but this doesn't work because it isn't a new window and it doesn't have a URL or anything.
I also tested many CoreWebView2 settings which made sense,like before no useful results
Does somebody know if there is a setting or something which i have to enable/disable in WebView2 to disable these notifications?
If any further information is required please ask me!
You need to look at the Permissions Requested event for mic and camera.
async private void InitializeWebView2()
{
await webView21.EnsureCoreWebView2Async();
webView21.CoreWebView2.PermissionRequested += CoreWebView2_PermissionRequested;
}
private void CoreWebView2_PermissionRequested(object sender, CoreWebView2PermissionRequestedEventArgs e)
{
Debug.WriteLine(e.PermissionKind.ToString());
e.State = CoreWebView2PermissionState.Allow;
}
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.
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
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();
}
I've created a WPF Desktop Application with C# and placed a System.Windows.Controls.WebBrowser.
Typing this (Where {0} is my app id/key)
https://www.facebook.com/dialog/oauth?&client_id={0}&response_type=token&redirect_uri=https://www.facebook.com/connect/login_success.html&display=popup&scope=publish_stream,offline_access
manually into my firefox/ie/whatever and going to the workflow sends my back to
https://www.facebook.com/connect/login_success.html#access_token=TOKEN
that's great so far.
But navigating my System.Windows.Controls.WebBrowser to the workflow redirects this browser to
https://www.facebook.com/connect/login_success.html
WITHOUT the access token. What am I doing wrong?
I hit something like this while implementing Facebook PowerShell Module. You may be hitting a bug in WPF per http://facebooksdk.codeplex.com/discussions/261528. I had to drop back to WinForms for implementing the login capability only. This also fixed an odd crash-on-exit which I had been experiencing.
I've come up with a workaround. The WPF browser cuts off the hash-part of an url, the WinForms webbrowser doesn't.
So watch this code behind of my XAML window which I'm going to use for getting Facebook app permissions from a user:
public partial class DiagnosticBrowserWindow : Window
{
public DiagnosticBrowserWindow(string urlToRequest)
{
InitializeComponent();
System.Windows.Forms.WebBrowser shadowBrowser = new System.Windows.Forms.WebBrowser();
shadowBrowser.Navigated += (sender, e) =>
{
// the access token is now
// here in e.Url
};
this.Browser.Navigated += (sender, e) =>
{
if (this.Browser.Source.AbsoluteUri.StartsWith("https://www.facebook.com/connect/login_success.html"))
{
shadowBrowser.Navigate(urlToRequest);
}
};
this.Browser.Navigate(urlToRequest);
}
}
This is working, because as soon the app permissions have been granted (which we detect by detecting a redirect to login_success.html) we send the shadow browser (which is a WinForms Webbrowser) to the inital request page which is:
https://www.facebook.com/dialog/oauth?&client_id={0}&response_type=token&redirect_uri=https://www.facebook.com/connect/login_success.html&display=popup&scope=publish_stream,offline_access
Facebook will detect, that the permissions already have been granted and send the shadowBrowser back to login_success.html and this time you can read the hash-part.