【问题标题】:WebBrowser to Gecko: Injecting javascriptsWebBrowser 到 Gecko:注入 javascripts
【发布时间】:2015-11-03 01:29:01
【问题描述】:

我正在尝试将使用 WebBrowser 控件的应用程序移植到 Gecko。 我唯一无法管理的是 javascript 注入来访问刚刚下载的页面的全局变量。 例如,如果 javascript 是:

function get_players()
{
    strout = "no data";
    try
    {
        if (players_ar == null) 
            return "Javascript error: players_ar is null";
        else
            return players_ar[0]["fp"];
    }
    catch (err)
    {
        strout += ";Javascript error = " + err;
    }

    return strout;
}

players_ar 是我刚刚在浏览器中加载的页面中的全局变量(数组)。将脚本的文本保存在变量 function_text 中,并使用 WebBrowser 如下调用脚本:

HtmlElement head = webBrowser.Document.GetElementsByTagName("head")[0];
HtmlElement scriptEl = webBrowser.Document.CreateElement("script");
IHTMLScriptElement element = (IHTMLScriptElement)scriptEl.DomElement;
element.text = function_text;
HtmlElement res = head.AppendChild(scriptEl);
pl_data = (string)webBrowser.Document.InvokeScript("get_players");

我成功返回了 player_ar 元素的值。 对 Gecko 做同样的事情,但没有成功:

GeckoHtmlElement head = webBrowser.Document.GetElementsByTagName("head")[0];
GeckoElement scriptEl = webBrowser.Document.CreateElement("script");

nsIDOMHTMLScriptElement element = (Gecko.nsIDOMHTMLScriptElement)scriptEl.DOMElement;
element.SetTextAttribute(new nsAString(Resources.players_loader));
GeckoNode res = head.AppendChild(scriptEl);

using (var java = new AutoJSContext(GlobalJSContextHolder.BackstageJSContext))
{
    string result;
    const string javascript =
        @"
        function get_players()
        {
            strout = 'no data';
            try
            {
                if (players_ar == null)
                    return 'Javascript error: players_ar is null';
                else
                    return players_ar[0]['fp'];
            }
            catch (err)
            {
                strout += ';Javascript error = ' + err;
            }

            return strout;
        }
        get_players();
        ";

    if (java.EvaluateScript(javascript, (nsISupports)webBrowser.Document.DomObject, out result))
    {
        MessageBox.Show(String.Format("javascript returned '{0}'", result));
    }
}

在这种情况下,返回值为:“no data;Javascript error = ReferenceError: player_ar is not defined”,这意味着它会阻止检查 player_ar 是否为 null,因为根本没有声明变量。

我想知道 Gecko 的行为与 IE 不同,也许第一个浏览器在加载页面后不保存变量环境。 请帮忙,我的想法已经用完了。

【问题讨论】:

    标签: javascript webbrowser-control gecko


    【解决方案1】:

    经过一周的尝试,结果发现我使用了错误的功能。它仍然是 EvaluateScript,但我不知道为什么这个原型可以工作,而另一个不能工作。我直接向 geckofx 人员询问并帮助其他面临同样问题的人,我发布了他们的回复(感谢 Andrey Filippov)。 代码如下(它确实有效,因此也经过测试):

    const string function_text =
        @"
            function get_players()
            {
                strout = 'no data';
                try
                {
                    strout += ';clubname = ' + this.screenX;
    
                    if (players_ar == null)
                        return 'Javascript error: players_ar is null';
                    else
                        return players_ar[0]['fp'];
                }
                catch (err)
                {
                    strout += ';Javascript error = ' + err;
                }
    
                return strout;
            }                    
            ";
    
    GeckoElement scriptEl = webBrowser.Document.CreateElement("script");
    
    scriptEl.TextContent = function_text;
    GeckoNode res = webBrowser.Document.Head.AppendChild(scriptEl);
    
    using (var java = new AutoJSContext(webBrowser.Window.JSContext))
    {
        JsVal result = java.EvaluateScript("get_players()", webBrowser.Window.DomWindow);
        MessageBox.Show(result.ToString());
    }
    

    【讨论】:

    • 可能是由于更新。现在使用如下:webBrowser.Window,而不是webBrowser.Window.JSContext
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-26
    相关资源
    最近更新 更多