【问题标题】:Call a function written on VB from a JScript code (classic ASP)从 JScript 代码调用用 VB 编写的函数(经典 ASP)
【发布时间】:2023-03-05 01:26:01
【问题描述】:

目前我必须处理用 VB 编写的遗留系统。我不擅长 VB 和 ASP,所以我决定用 JScript 编写这个系统的新代码。

但是,两种语言之间的互操作性存在一些问题:即,当我尝试调用在<script language="vbscript"> 标记中声明的某个函数时,它会失败并出现“Object expected”错误(如果页面语言是 VBScript),反之亦然。

即如下代码:

inc.asp

<script language="vbscript" runat="server">
Sub VBTestFunction(Message)
    Response.Write "VBTestFunction: " & Message
End Sub
</script>
<script language="javascript" runat="server">
function JSTestFunction(Message) {
    Response.Write("JSTestFunction: " + Message);
}
</script>

testjs.asp

<%@ Language="JavaScript" %>
<!-- #include file="inc.asp"-->
<script language="javascript" runat="server">
    VBTestFunction("from javascript");
    JSTestFunction("from javascript");
</script>
<script language="vbscript" runat="server">
    Call VBTestFunction("from vbscript")
    Call JSTestFunction("from vbscript")
</script>

失败并出现以下错误:

VBTestFunction: from vbscript
Microsoft VBScript runtime error '800a000d'
Type mismatch: 'JSTestFunction'
/test.asp, line 9

(如果我要评论特定的行,其他三个语句都可以正常工作);将页面语言设置为 VBScript

<%@ Language="VBScript" %>
<!-- #include file="inc.asp"-->
<script language="javascript" runat="server">
    VBTestFunction("from javascript");
    JSTestFunction("from javascript");
</script>
<script language="vbscript" runat="server">
    Call VBTestFunction("from vbscript")
    Call JSTestFunction("from vbscript")
</script>

失败并出现以下错误:

Microsoft JScript runtime error '800a138f'
Object expected
/test.asp, line 4

(同样,如果我将特定行注释掉,其他三个语句也可以正常工作)。

在同一个应用程序中混合 VB 和 JS 有一个 MSDN article,但从文章看来,示例代码应该可以工作,因为 TestFunction 是在另一个文件中声明的,毕竟是一个函数。

有没有办法让这一切工作,并从 VB 和 JS 代码中调用 VBTestFunctionJSTestFunction?我想应该有一个,否则JS和VB混合就没有意义了。

【问题讨论】:

  • 仔细查看您提到的文章,特别是它说“服务器脚本执行顺序”的部分。你的问题就在那里。
  • 本文专门划清了主代码流(“内联服务器脚本”)和子程序声明之间的界限。从文章看来,一个子程序可以用任何语言声明,我可以用任何语言调用它。

标签: asp-classic vbscript jscript


【解决方案1】:

我一直在关注这个问题,Salman 已经回答了很多,但有些事情需要澄清。首先,被引用的文章存在关键问题。它说执行顺序是这样的:-

1.以非默认语言在元素中编写脚本
2.内联脚本
3.以默认语言在元素中编写脚本

它是错误的,或者至少它已经过时了(它毕竟引用了 IIS4)。 “内联脚本”(即默认语言的脚本)的处理方式与相同语言的脚本元素没有任何不同。

下面是解释正在发生的事情的方法。

  • 在任何解析开始之前,所有包含点都被解析并被包含文件中的内容替换,以创建单个词汇“文件”。这是在进行任何解析之前创建的。

  • 从这个“文件”中收集每种语言的脚本代码。您可以想象在找到每个块时附加多个文件(每种语言一个)。请注意,这就是为什么默认语言的 &lt;% %&gt;&lt;script runat="server" 实际上无法区分的原因。

  • 任何静态内容(即runat="server" 脚本标记或&lt;% %&gt; 之外的内容)都被视为默认语言代码的一部分。将创建一个特殊形式的Response.Write 将静态内容字节逐字发送到响应,并将其附加到原始文件中的默认语言代码。

  • 现在我们有一个或多个脚本准备好由各自的脚本引擎处理。非默认语言脚本首先被解析执行。为函数或变量创建的任何全局标识符都将添加到脚本环境中。但是,由于此时根本没有处理默认语言脚本,因此它可能随后添加到全局脚本环境中的任何内容都不可用。

  • 在解析和执行默认语言脚本时,由先前语言脚本创建的所有全局标识符都将添加到脚本环境中,因此可以从内联代码中使用。

您应该仔细注意默认语言函数可以在条件下由非默认语言的函数中的代码调用对非默认函数的调用可以追溯到默认语言的内联执行。

例如,如果默认语言是 JScript,只要调用 fnA 作为JScript 的内联执行。 IOW JScript 可以调用 VBScript,VBScript 又可以调用 VBScript 等等,限制因素是在这种情况下这个链的顶部必须是 JScript 的引擎。

在您的示例代码中,您的 VBScript 全局(内联)级别的代码试图调用以默认 JScript 语言声明的函数。如果您按照上面的项目符号进行操作,您将看到在执行时被调用的函数不存在。

【讨论】:

  • 对不起,文中提到的执行顺序仍然有效。在 IIS7 上运行 this scriptthisthis 并记下执行顺序——它保持不变,与文章中描述的完全相同。您回答中的一些断言是错误的,特别是那些与执行顺序有关的断言。
  • 至于您的注释:您的意思是,全局名称解析发生在运行时,因此,基本上,所有函数调用都是内联的,然后生成的代码在“非代码中的代码”规则下执行-默认语言先执行,默认语言代码最后执行”?
【解决方案2】:

我鼓励您不要混合使用脚本语言。在the article you mentioned 中,有一个标题为“服务器脚本执行顺序”的标题:

...但是,您将受到执行顺序的摆布 IIS ASP 处理器。例如,如果您创建服务器脚本并运行它 在 IIS 4.0 中,你会发现这个执行顺序:

  1. 非默认语言的
  2. 内联脚本
  3. 默认语言的

请记住,下面是 testjs.asp 脚本的执行方式,cmets 指示执行顺序:

<%@ Language="JavaScript" %>
<script language="vbscript" runat="server">
    '' #1
    Sub VBTestFunction(Message)
        Response.Write "VBTestFunction: " & Message
    End Sub
</script>
<script language="javascript" runat="server">
    // #3
    function JSTestFunction(Message) {
        Response.Write("JSTestFunction: " + Message);
    }
</script>
<script language="javascript" runat="server">
    // #4
    VBTestFunction("from javascript");
    JSTestFunction("from javascript");
</script>
<script language="vbscript" runat="server">
    '' #2
    Call VBTestFunction("from vbscript")
    Call JSTestFunction("from vbscript")
</script>

注意导致错误的行:

Call JSTestFunction("from vbscript")

它的执行顺序是#2;此时函数JSTestFunction未定义(在执行顺序后面定义)。

现在是 testvbs.asp 文件:

<%@ Language="VBScript" %>
<script language="vbscript" runat="server">
    '' 3
    Sub VBTestFunction(Message)
        Response.Write "VBTestFunction: " & Message
    End Sub
</script>
<script language="javascript" runat="server">
    // 1 
    function JSTestFunction(Message) {
        Response.Write("JSTestFunction: " + Message);
    }
</script>
<script language="javascript" runat="server">
    // 2
    VBTestFunction("from javascript");
    JSTestFunction("from javascript");
</script>
<script language="vbscript" runat="server">
    '' 4
    Call VBTestFunction("from vbscript")
    Call JSTestFunction("from vbscript")
</script>

导致错误的行:

VBTestFunction("from javascript");

同样,VBTestFunction 在定义之前被调用。解决方案是尽量不要混合脚本语言。如果绝对有必要,请修改脚本的顺序。

编辑 -- 示例

如果您设置了@ Language="JavaScript",那么此代码应该可以按预期工作:

<!-- inc.asp-->
<script language="vbscript" runat="server">
    Sub VBTestFunction(Message)
        Response.Write "VBTestFunction: " & Message
    End Sub
</script>
<%
    function JSTestFunction(Message) {
        Response.Write("JSTestFunction: " + Message);
    }
%>

<!-- testjs.asp -->
<%@ Language="JavaScript" %>
<!-- #include file="inc.asp"-->
<%
    // at this point, both functions are available
    VBTestFunction("from inline JavaScript");
    JSTestFunction("from inline JavaScript");
%>

如果要使用@ Language="VBScript",则必须重新排列所有代码:

<!-- inc.asp-->
<script language="javascript" runat="server">
    function JSTestFunction(Message) {
        Response.Write("JSTestFunction: " + Message);
    }
</script>
<%
    Sub VBTestFunction(Message)
        Response.Write "VBTestFunction: " & Message
    End Sub
%>

<!-- testvbs.asp -->
<%@ Language="VBScript" %>
<!-- #include file="inc.asp"-->
<%
    ' at this point, both functions are available
    VBTestFunction("from inline VBScript")
    JSTestFunction("from inline VBScript")
%>

【讨论】:

  • 我提到的那篇文章明确指出,它只对执行某些操作的代码很重要,对过程声明不重要。您是说不可能从任何用非主要语言编写的代码调用以主要语言编写的函数吗?
  • 你提到的文章给了你一些建议(和陷阱)关于如何去混合像 这样的脚本语言......要么仅将 .我会看看我是否可以重新安排您的代码以使其正常工作。
  • 我建议您不要混合使用脚本语言。 似乎没有必要。
  • @cheeso:这似乎没有必要,但据我所知,这是一个很好的建议。评估多语言脚本块的顺序不允许您编写合理的程序代码。
  • @SalmanA:我同意用多种语言清楚地编写代码块是自找麻烦。但是,我专门回应了您的陈述“不允许您编写明智的程序代码”,这实际上是完全矛盾的。混合语言不会阻止“合理的程序代码”,实际上使用“合理的程序代码”是避免混合语言问题的方法。例如,开发人员可能有一个广泛的 Javascript 函数库,他们想借用这些函数的特性。混合语言可能比移植部分库更可取。
【解决方案3】:

我不知道所有规则,但这对我有用:

test.asp:

<%@ language="JavaScript" %>

<script language="VBScript" runat="server" src="mix2.vbs"></script>

<script language="JavaScript" runat="server">
    TestFunction("from javascript");
</script>

mix2.vbs:

Sub TestFunction (message)
    Response.Write message
End Sub

注意:

  • 在包含的 vbs 文件中没有 &lt;script&gt; 标记。
  • 顶部的&lt;%@ language="..." %&gt; 标记应指示“主要”语言。然后,使用辅助语言(在您的情况下为 VBScript)的 &lt;script&gt; 块将被解释并可用于主要语言的任何代码。

可能相关:How can I use Javascript OO classes from VBScript, in an ASP-Classic or WSH environment?

【讨论】:

  • 我修改了我的答案。您的建议修复了特定的原始问题,但破坏了从 VB 代码调用 JS 函数的能力。
  • 其实不然。您只需要重新调整语言声明即可。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-29
相关资源
最近更新 更多