0

我正在开发一个与(第三方提供的)网络应用程序交互的 vb.net 应用程序,以提供额外的功能(例如删除菜单项、从页面中提取信息等)。该网络应用程序完全由 javascript 驱动,但托管在 asp.net 中,并且仅与 Internet Explorer 一起使用。

我正在尝试从 javascript 对象中读取属性并执行它的一些功能。通过获取脚本所在的 iframe 的 mshtml.HTMLDocument 并使用以下代码,我设法获取了 javascript 对象:

Dim jsObject as Object
jsObject = htmldoc.Script.jsObject

jsObject 作为 {System.__ComObject} 存在,我可以使用它来执行它的任何功能或读取它的属性,如下所示:

Dim value as String = jsObject.FunctionThatReturnsAString()
jsObject.FunctionTHatDoesSomethingInWebApp("Param1", "Param2")

这很好用。但是,当我离开带有 jsObject 的页面/框架并返回到它时,当再次从框架中获取 javascript 对象时(即执行以下行),相同的代码会引发异常:

jsObject = htmldoc.Script.jsObject

例外:未找到成员。(来自 HRESULT 的异常:0x80020003 (DISP_E_MEMBERNOTFOUND))

如果我停止调试并重新启动,它会再次工作(直到我离开页面等)。就我的应用而言,我不确定发生了什么导致 javascript 对象消失。我假设这是由于我的应用程序持有对 COM 对象的引用,我需要以某种方式释放它(特别是因为它有 MarshalByRefObject 的基本类型 - 这很有意义,因为它在应用程序域之间传递)。

为什么会这样?有没有更好的方法来访问 javascript 对象,它的属性和函数?

4

1 回答 1

1

在我的情况下,我发现了什么是实现我需要的更好的方法。我不是直接将 jsObject 作为 COM 对象访问(并担心编组等),而是使用:

  • execScript 调用没有返回值的函数或
  • 在我正在工作的框架中创建一个隐藏的 div 元素,将该 div 的 innerHTML 设置为等于我有兴趣使用 execScript 的任何 javascript 变量/函数返回值,然后从 DOM 中单独读取该值

要读取变量/函数返回,我使用以下 vb.net 函数:

Private Function getJScriptVariable(ByVal JScript As String)
    Dim command As New StringBuilder()
    command.Append("var e = document.getElementById('Matt_JScriptReturn');")
    command.Append("if (e == null) {")
    command.Append("var e = document.createElement('div');")
    command.Append("e.id = 'Matt_JScriptReturn';")
    command.Append("e.type = 'hidden';")
    command.Append("document.body.appendChild(e);")
    command.Append("}")
    command.Append("e.innerHTML = ")
    command.Append(JScript)
    command.Append(";")

    'fMaster is the frame containing the javascript's mshtml.IHTMLWindow2
    fMaster.execScript(command.ToString(), "JScript")

    'N.B. fMaster_Document is the fMaster's mshtml.HTMLDocument
    Return fMaster_Document.getElementById("Matt_JScriptReturn").innerHTML

    'Optionally execScript to remove element from DOM at this point
End Function

然后我将按如下方式使用该功能(尊重我在原始问题中的示例):

Dim value as String = getJScriptVariable("jsObject.FunctionThatReturnsAString()")

要执行 javascript 代码而不需要返回值,我只需按如下方式执行它:

fMaster.execScript("jsObject.FunctionTHatDoesSomethingInWebApp('Param1', 'Param2')")

我仍然很想知道为什么我之前遇到了 javascipt 对象在离开页面并返回后无法访问的问题,但是这解决了我的问题,所以我现在很高兴!我希望这在某些时候对其他人有所帮助。

于 2012-08-16T09:44:27.897 回答