Ошибка класса не определена при смешивании языков сценариев

Следующий код:

<%
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

Но почему?

Если я вызываю функцию page1() из VBScript, то она работает как положено.

Спасибо,

Барри

РЕДАКТИРОВАТЬ 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

вместо этого я получаю:

Класс не определен: "Страница"

5 ответов

Я не могу найти точный источник для этого, но я почти уверен, что VBScript New ключевое слово может использоваться только для создания экземпляров классов, определенных в VBScript с использованием Class ключевое слово. Вместо этого вы должны написать "фабричную" функцию в 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>

Вы попали в ограничение двигателя 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> блоки на разных языках обрабатываются отдельно.

Чтобы узнать больше, посетите эту статью базы знаний MSDN.

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

Проблема в порядке исполнения. У меня не установлен 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

Вам необходимо изменить порядок сценариев. Когда ваш скрипт встречает вызов функции, он позволяет этому функциональному блоку находиться в любом блоке кода на странице в той же области видимости. Это не так при создании объектов. При создании объектов объектный код должен обрабатываться перед строкой создания. Сценарии для всех намерений и целей выполняются линейно.

Другие вопросы по тегам