Ошибка класса не определена при смешивании языков сценариев
Следующий код:
<%
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
Вам необходимо изменить порядок сценариев. Когда ваш скрипт встречает вызов функции, он позволяет этому функциональному блоку находиться в любом блоке кода на странице в той же области видимости. Это не так при создании объектов. При создании объектов объектный код должен обрабатываться перед строкой создания. Сценарии для всех намерений и целей выполняются линейно.