Reputation: 20494
In my Form, I added a WebBrowser and a TextBox on which I would like to display the current loaded Url.
Note what the Microsoft Docs says:
WebBrowser.Navigating event:
Occurs before the WebBrowser control navigates to a new document
WebBrowser.Navigated event:
Occurs when the WebBrowser control has navigated to a new document and has begun loading it.
...
Handle the DocumentCompleted event to receive notification when the WebBrowser control finishes loading the new document.
WebBrowser.DocumentCompleted event:
Occurs when the WebBrowser control finishes loading a document
...
Handle the DocumentCompleted event to receive notification when the new document finishes loading. When the DocumentCompleted event occurs, the new document is fully loaded
The order at which the events are fired is: Navigating, Navigated and DocumentCompleted, so I'm handling those events to try properly update the current url:
private void WebBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e) {
this.TextBox1.Text = e.Url.ToString();
}
private void WebBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e) {
this.TextBox1.Text = e.Url.ToString();
}
private void WebBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) {
this.TextBox1.Text = e.Url.ToString();
}
The problem is that for some reason the url does not seem to properly update for some websites...
For example when navigating through Google's search engine, if I do click on the Google Images button, the url updates to "http://www.google.com/blank.html". Also, the urls that I get to display in my TextBox are not the same exact urls as I can see in Firefox or Chrome's address bar; for some reason my obtained urls have additional parameters in the query.
See it by yourself:
https://i.sstatic.net/0PX5A.gif
Is there any workaround to improve this annoying behavior so I can display the current url with efficiency as Firefox or Chrome does?. I mean, for example Firefox and Chrome will not show "http://www.google.com/blank.html" in the addres bar, neither will not show the url queries with additional parameters as I got to display (which you can see in the GIF image above).
Please note that the problem with Google website is just as an example. I'm asking for a universal solution due this issue occurs with many more websites.
Also note that if instead the WebBrowser component I use CefSharp's chromium based web browser, adapting my code to reproduce the same as I was doing to display/update the current url, then the problem is partially gone...
Using CefSharp does not shows "http://www.google.com/blank.html" when navigating through Google Images, however the query of the urls still contain additional parameters / many differences in comparison from the urls displayed in Firefox or Chrome browsers. And apart from that, I would like to avoid using CefSharp just for solving this kind of issue...
Upvotes: 2
Views: 1594
Reputation: 8498
Instead of URL in the event args, use URL from the web browser control:
string url = webBrowser1.Url.ToString();
What you are missing here is that the HTML page can contain iframe elements. An iframe encapsulates HTML Window and the contained HTML Document, and it performs its own navigation. The navigation events of the WebBrowser control fire for both the top window (for which you want to display the URL) and for the iframe's. You will have to distinguish between the two.
Specifically, in your case http://www.google.com/blank.html
comes from an iframe:
<html> <!-- top window -->
<body> <!-- top window's document -->
<iframe src="http://www.google.com/blank.html">
<!--
here the browser will load and "insert" HTML of blank.html
lines below don't exist in the original HTML
they are loaded and "inserted" here by the browser
-->
<html> <!-- iframe's window -->
<body> <!-- iframe's window's document -->
<!-- the body can contain additional iframes... -->
</body>
</html>
</iframe>
</body>
</html>
In general, the DOM of an HTML page is a tree of HTML Window objects, with the root window returned by the window.top
property. Depending on how the page is designed, iframe's can be visible or hidden; they can be rendered in HTML by server, and also be manipulated, created, or deleted dynamically in the browser through JavaScript:
src
attribute. If neither src
nor embedded contents are specified, the navigation URL will be about:blank
.src
attribute of an existing iframe is modified, the iframe will perform navigation to the new src
.window.location
is modified of either top or iframe HTML Window, it will perform navigation to the new location
.However, determining which HTML Window (top or iframe) performs the navigation doesn't seem to be a trivial task, so a simpler approach would be just getting URL of the top window:
string url = webBrowser1.Url.ToString();
or after the DocumentCompleted
event:
HtmlWindow topWindow = webBrowser1.Document.Window;
string url = topWindow.Url.ToString();
Upvotes: 2
Reputation: 43941
The DocumentCompleted
can be fired multiple times for a given URL, because a page can contain iframe
s that also trigger the event. So I suggest that you update the textbox at Navigating
and Navigated
events only.
Upvotes: 2