【问题标题】:How to detect Javascript execution in WebBrowser control如何检测 WebBrowser 控件中的 Javascript 执行
【发布时间】:2012-03-22 23:42:34
【问题描述】:

我的 C# 应用程序中有一个 WebBrowser 控件。网络浏览器在用户的控制之下,即他可以在网络上加载他的电脑可以访问的任何网页(当然受限于代理、hosts文件等)。

当网页浏览器组件中加载的页面内有 Javascript 调用时,我需要知道并得到通知。

第一个例子:给定这样的链接

<a href="javascript:void(0)" onclick="jsFunct();">test</a>

当用户点击链接时,我需要知道函数“jsFunct”已被调用。

第二个例子:给定一个电话

<script type="text/javascript">
    window.setTimeout("jsFunct()", 1000);
</script>

我需要知道,脚本执行后1秒,函数jsFunct已经被调用。

最好的办法是在函数被调用时触发一个事件。如果事件可以执行 Javascript 代码,或者至少是参数中的函数名,那也很棒。

编辑:

即使问题与 webbrowser 组件有关,任何允许用户检测 javascript 激活(甚至通过 js)的东西都可以,能够注入处理 javascript 事件并将其传递给 wb 控件的 js触发一些它可以处理的事件。

【问题讨论】:

    标签: javascript c# browser webbrowser-control dom-events


    【解决方案1】:

    当在 JavaScript 中触发全局函数时,您可以使用 window.external 调用 C# 方法。有关 window.external 的详细信息,请参阅WebBrowser Control Overview

    您需要设置 ObjectForScripting: Webbrowser control's window.external is ALWAYS null. 才能使其工作。

    采用@Krishna 的回答来添加 JavaScript(但删除 jQuery,因为它不需要):

    private void addScript(HtmlElement head, string scriptSource) 
    { 
    HtmlElement lhe_script = head.Document.CreateElement("script"); 
    IHTMLScriptElement script = (IHTMLScriptElement)lhe_script.DomElement; 
    script.src = scriptSource;
    head.AppendChild(lhe_script);            
    } 
    
    addScript(WebBrowser.Head, @"InjectMonitor.js");
    

    下面的 JavaScript (InjectMonitor.js) 将查找所有全局函数并附加您指定的处理程序:

    function augment(withFn) {
        var name, fn;
        for (name in window) {
            fn = window[name];
            if (typeof fn === 'function') {
                window[name] = (function(name, fn) {
                    var args = arguments;
                    return function() {
                        withFn.apply(this, args);
                        fn.apply(this, arguments);
    
                    };
                })(name, fn);
            }
        }
    }
    
    augment(function(name, fn) {
        console.log("calling " + name, fn);
    
        // window.external.yourC#method
    });
    

    在这个例子中,取自Adding Console Log to Every Function,它只是记录对控制台的调用;但是使用 window.external 您可以将一些消息发送回您的 C# 应用程序,其中包含从客户端调用的函数的详细信息。

    最后,这是一个 JS Bin 示例(运行它,不要忘记控制台):JS Bin Example

    【讨论】:

    • 目前我没有太多时间来测试这个,你能解释一下我如何用window.external 检测到网页中对特定js函数的调用吗?一个小的代码示例也将不胜感激
    • 已更新,我添加了相关的 JS 并希望完整的解决方案。
    • 正是我所需要的,真的很高兴奖励赏金并解决这个问题,谢谢!
    • 没问题,仅供参考,我曾经玩过 Function.prototype.call 认为可以做到这一点,但除非调用 call(),否则永远无法让它工作。
    • 什么是WebBrowser.Head?这是一个例子,你的意思是WebBrowser.Document.GetElementsByTagName("head")[0]?
    【解决方案2】:

    在浏览器加载事件上,

    1. 注入 Jquery
    2. 注入监控脚本

    private void addScript(HtmlElement head, string scriptSource) 
    { 
    HtmlElement lhe_script = head.Document.CreateElement("script"); 
    IHTMLScriptElement script = (IHTMLScriptElement)lhe_script.DomElement; 
    script.src = scriptSource;
    head.AppendChild(lhe_script);            
    } 
    
    addScript(Webbrowser.Head, @"<Change File Path here>jquery.min.js");
    addScript(WebBrowser.Head, @"InjectMonitor.js");
    

    您的文件 InjectMonitor.js 应该是这样的

     $(document).ready(function () { 
            //Add click event for every anchor on the page loaded- note this merely alerts text on click. you can however add your own function
            $("a").click(function (e) { alert($(this).text()); return false;}) 
        }); 
    

    【讨论】:

    • +1 为我指明了正确的方向,让我们做更多的工作来得到答案
    • 请告诉我你们相处得如何。如果你被困在某个地方,我也会尝试在我的最后设置这个项目。这是一个很好的,相信很有可能
    • 您能更好地解释一下“监控脚本”是什么意思吗?谢谢
    • jQuery 支持同一事件的多个处理程序,因此如果您想知道某人何时单击了某个锚点(例如),您可以将代码添加到 MonitorScript(请参阅上面我编辑的答案)
    • 我相信这就是帖子所说的,包装对 webbrowser 代码中加载的现有 javascript 代码(不在您的控制范围内)的额外调用。即,对于页面中的每个 javascript 函数,向您的侦听器注入一个调用(这是/将在 MonitorScript.js 中定义)。让我看看我是否可以为您获取此代码。我这周不在,但这将是一项值得思考的好任务
    【解决方案3】:

    克里希纳回答的是纯 javascript 附加到事件,但是我看到您可能需要将它附加到所有标签(a、p、div、输入)等以及附加到每个标签的所有事件.

    我相信另一种方法是使用 .net 中可用的 BHO(浏览器帮助对象),如果没有,并且您擅长 VC++ 和 MFC,您也可以使用 Windows Hooks。

    【讨论】:

    • 将javascript附加到事件的问题是它没有检测到使用setTimeout之类的函数执行的javascript的执行。此外,如果点击没有触发 javascript 调用怎么办?不好。无论何时发生,我都需要检测 JavaScript 函数的执行,它应该在事件处理程序中调用,由超时触发还是以其他方式触发。
    猜你喜欢
    • 2013-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-19
    • 1970-01-01
    • 2011-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多