Capture #Ajax requests with #webbrowser control in C#
If you embed a webbrowser control in a C# application, you can interact with third party websites in ways that you would not be permitted to within a standard webpage. One limit though, is although you can detect page changes, you can’t detect ajax calls. Which is one thing you may like to read.
But, a workaround is to inject javascript that hooks into the XMLHttpRequest.open method, and then reports this back to the host application.
First you need a function to inject Javasript into the page;
var strJs = File.ReadAllText(“inject.js”);
webBrowser.Document.InvokeScript(“eval”, new object[] { strJs });
Here is the injected javascript:
(function (open) {
XMLHttpRequest.prototype.open = function (method, url, async, user, pass) {
this.addEventListener(“readystatechange”, function () {
if (this.readyState == 4) {
window.external.Hook(this.responseText);
}
}, false);open.call(this, method, url, async, user, pass);
};})(XMLHttpRequest.prototype.open);
Where window.external.Hook is going to be defined in C# as follows;
[ComVisible(true)]
public class ScriptManager
{
public void Hook(string message)
{
System.Diagnostics.Debug.WriteLine(message);
}
}
You pass a ScriptManager instance to the webbrowser control as follows;
webBrowser.ObjectForScripting = new ScriptManager();
Now, whenever an ajax call is made, it is written to the debug console.
To read more about IE in C#, check out this article:
http://www.webtropy.com/articles/InternetExplorer.asp?Internet%20explorer
Thank you, it was very helpful to me.
LikeLike
Credit due to John Whiteman for this suggested improvement;
(function (open) {
XMLHttpRequest.prototype.open = function (method, url, async, user, pass) {
this.onreadystatechange = function (){if (this.readyState == 4) {window.external.Hook(this.responseText);}};
open.call(this, method, url, async, user, pass);
};
})(XMLHttpRequest.prototype.open);
LikeLike
When I try it I just get an error “unable to get property Hook of undefined or null reference.
LikeLike
Its ok now, I didn’t realize the ScriptManager class had to be embedded in the Form class, I just had it as a stand a lone class to start with.
LikeLike
Thanks for the posst
LikeLike