混合脚本语言时类未定义错误

时间:2012-02-15 09:00:10

标签: asp-classic vbscript

以下代码:

<%
Response.Write("VB comes second!")

'page1()
Dim p
Set p = New Page
%>

<script language = "Python" runat="server">
Response.Write("Python comes first!")

class Page:
    def display_top(self):
        Response.Write("""
        <html>
        """)

    def display_body(self, body_text):
        Response.Write("<body>"+body_text+"</body>")

    def display_bottom(self):
        Response.Write("""
        </html>
        """)

def page1():
    p = Page()
    p.display_top()
    p.display_body("This is my body!")
    p.display_bottom()
</script>

给出错误:

Error Type:
Microsoft VBScript runtime (0x800A01FA)
Class not defined: 'Page'
/website/index.asp, line 6

但为什么?

如果我从VBScript中调用函数page1(),那么它按预期工作。

谢谢,

百里

编辑1:

此:

<script language = "Python" runat="server">
class Page:
    def display_top(self):
        Response.Write("<html>")
</script>

<%
Dim p
Set p = server.createobject("Page")
%>

给出错误:

无效的班级字符串

如果我使用:

Set p = New Page

相反,然后我得到:

未定义的类:'Page'

5 个答案:

答案 0 :(得分:1)

你正在那里遇到一个asp引擎限制。

<script runat=server>块中的代码可能会在不同的时间运行。

服务器脚本执行顺序

内联服务器脚本从上到下依次运行。您可以在服务器脚本中定义可调用例程(函数或子例程),并根据需要调用它们。

所有内联脚本必须使用相同的语言,即页面顶部@指令中指定的语言。因此,您不能在内联脚本中混合使用脚本语言。

“但是等等!”你可能会说。理论上可以将类似内联的脚本放入<SCRIPT>元素中,即元素中的脚本不属于函数或子例程,如下例所示:

<% Response.Write("Some inline script<BR>")%>
<SCRIPT LANGUAGE="VBScript" RUNAT="Server">
    Response.Write("Script in a SCRIPT element<BR>")
</SCRIPT>

是的,你可以这样做。 * 然而,您将受到IIS ASP处理器执行顺序的支配。 *

订购脚本块

当您混合语言时,<SCRIPT>块在页面中显示的顺序可能会对它们是否正常工作产生影响。考虑这个简单的内联VBScript脚本调用JScript编写的函数的情况:

<SCRIPT LANGUAGE="VBScript">
    ' Calls a JScript function
    aNumber = 2
    doubledNumber = doubleMe(aNumber)
    document.write("The answer is " & doubledNumber)
</SCRIPT>

<SCRIPT LANGUAGE="JavaScript">
    function doubleMe(aNumber){
        return aNumber * 2;
    }
</SCRIPT>

这不起作用。更具体地说,document.write语句将向页面写入一个空字符串。为什么?因为在处理VBScript块时,以下JScript <SCRIPT>块尚未被读取,解析并可供页面使用。当浏览器处理页面中的脚本块时,它从上到下工作。

在这种情况下,只需反转脚本块的顺序即可解决问题。事实上,这种类型的场景并不是那么常见 - 在大多数情况下,<SCRIPT>块包含在页面完全加载且所有元素都可用之前不会被调用的函数和子例程。尽管如此,您应该牢记页面是线性处理的,并且不同语言的<SCRIPT>块是分开处理的。

要了解详情,请访问this MSDN knowledge base article

答案 1 :(得分:1)

Proof that the class defined in one script block is reachable from another script block; 

<%
Response.Write "VBScript Here - 1 <p>"
hello()

apple.color = "reddish"
response.write (apple.getInfo())

%>

<script language=JavaScript runat=Server>
    Response.Write("Javascript here - 2 <p>");
    function hello()
    {
        Response.Write("Hello from JS <p>");
    }


    var apple = {
        type: "macintosh",
        color: "red",
        getInfo: function () {
            return this.color + ' ' + this.type + ' apple' + '<p>';
        }
    }


</script>

<%
    Response.Write("VBScript here - 3 <p>")
%>


<script language=JavaScript runat=Server>
    Response.Write("Javascript here - 4 <p>");  
</script>

<%
    Response.Write("VBScript here - 5 <p>")
%>


will give you this 
Javascript here - 2
Javascript here - 4
VBScript Here - 1
Hello from JS
reddish macintosh apple
VBScript here - 3
VBScript here - 5

答案 2 :(得分:1)

我无法找到明确的源代码,但我很确定VBScript New关键字只能用于使用Class关键字实例化VBScript中定义的类。你应该做的是在Python中编写一个“工厂”函数,它将返回一个新的Page对象。然后你可以从VBScript调用该函数。

我不懂Python,但是这里有一个VBScript和JScript的例子来说明这一点:

<%
Dim p
Set p = makePage("hello")
Response.Write p.foo
%>

<script language="JScript" runat="server">
function Page(foo) {
    this.foo = foo;
}

function makePage(foo) {
    return new Page(foo);
}
</script>

答案 3 :(得分:0)

问题是执行的顺序。我的服务器上没有安装python。所以我用JS和VB做了一个测试 - 这与我提到的问题相同。看一看;

<%
Response.Write "VBScript Here - 1 <p>"
%>

<script language=JavaScript runat=Server>
    Response.Write("Javascript here - 2 <p>");
</script>

<%
    Response.Write("VBScript here - 3 <p>")
%>


<script language=JavaScript runat=Server>
    Response.Write("Javascript here - 4 <p>");  
</script>

<%
    Response.Write("VBScript here - 5 <p>")
%>

will give you this

Javascript here - 2
Javascript here - 4
VBScript Here - 1
VBScript here - 3
VBScript here - 5

答案 4 :(得分:0)

您需要撤消脚本顺序。当您的脚本遇到函数调用时,它允许该功能块位于同一范围内页面上的任何代码块中。实例化对象时不是这样。在实例化对象时,必须在实例化行之前处理目标代码。脚本用于线性执行的所有意图和目的。