簡體   English   中英

導航后無法調用在注入到WebBrowser文檔中的代碼中創建的JavaScript對象的方法

[英]Can't call method of a JavaScript object created in code injected to WebBrowser's Document after navigating

我發現了其他類似問題,但並非完全如此,其解決方案無法解決特定問題。 我正在開發一個類似iMacros的Internet Explorer項目。 這是我的簡化代碼:

public partial class Form1 : Form
{
    public JSObject jsObject = new JSObject();
    int uniqueNameEnsurer = 0;

    public Form1()
    {
        InitializeComponent();
        webBrowser1.Navigate("www.google.com");
    }

    private void InvokeCode(string functionCode)
    {
        HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0];
        HtmlElement scriptEl = webBrowser1.Document.CreateElement("script");
        IHTMLScriptElement element = (IHTMLScriptElement)scriptEl.DomElement;
        element.text = "function MyInjectedFunction" + uniqueNameEnsurer + "(Param){" + functionCode + "}";
        head.AppendChild(scriptEl);
        webBrowser1.Document.InvokeScript("MyInjectedFunction" + uniqueNameEnsurer, new object[] { jsObject });
        uniqueNameEnsurer++;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        InvokeCode(@"
            function MyObject()
            {
                this.Something = 'hello';
                this.SomeFunc = function(){
                    alert('in SomeFunc!!!');
                }
            }

            Param.UserData = new MyObject();
        ");
    }

    private void button2_Click(object sender, EventArgs e)
    {
        webBrowser1.Navigate("www.bing.com");
    }

    private void button3_Click(object sender, EventArgs e)
    {
        InvokeCode(@"
            alert(Param.UserData.Something);
            Param.UserData.SomeFunc();
        ");
    }
}

[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
public class JSObject
{
    public object UserData;
}

所以,我要做的是,單擊button1(調用button1_Click ),然后單擊button2(調用button2_Click ),等待button2_Click秒鍾的加載時間,然后單擊button3(調用button3_Click )。 當我單擊button3時,我收到一條警報,提示“你好”(這意味着對象在導航后仍然存在),但是此后,我收到一條錯誤消息,提示“無法從釋放的腳本中執行代碼”。 這可能是某種安全性。 我發現一些帖子在談論,但沒有一個解決我的問題。 我可以通過將SomeFunc創建為字符串然后使用eval解決此問題,但這是一個令人討厭的解決方案。 如果我可以對C#代碼做任何事情,讓我按原樣(當然,而且可以正常工作)保持JavaScript代碼,那就太酷了。 如果沒有,那么最好的解決方法是什么,以便在導航后可以調用SomeFunc

這里有些事情我不太了解。 首先,在調用Navigate之后,我不會指望腳本在那里。 瀏覽完之后,我認為您應該重新注入所有想要的腳本。

其次,我沒有看到“ MyObject”的定義位置? 我看到“ new MyObject();” 在您的腳本中,但是我看不到任何地方定義的MyObject函數,因此未定義SomeFunc()不會令我感到驚訝。 假設樣本不完整。

最后,您應該研究在JSObject上實現IReflect和IExpando。 它可能會解決您所有的問題。

好吧,很顯然,僅用C#不可能做我想做的事情。 我將需要在JavaScript中實現某種對象序列化和反序列化系統,並在導航之前對UserData進行序列化,並在導航后對其進行反序列化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM