В этой главе даются основы серверной функциональности и различия между клиентским и серверным JavaScript. Здесь показано, как внедрять серверный JavaScript в HTML-файлы. Обсуждается, что происходит во время прогона программы на клиенте и на сервере, чтобы Вы могли разобраться во всём этом. В главе описано, как использовать JavaScript для изменения HTML-страницы, отправляемой клиенту, и, наконец, как распределить информацию между серверными и клиентскими процессами.
В главе имеются следующие разделы:
Серверный JavaScript имеет то же ядро языка, что и клиентский JavaScript, с которым Вы, возможно, уже знакомы. Задачи, выполняемые Вами при запуске JavaScript на сервере, несколько отличаются от задач, выполняемых при работе JavaScript на клиенте. Разные окружения и задачи обращаются к различным объектам.
Клиентская среда (браузер) является передним краем работы приложения. В этой среде, к примеру, Вы отображаете HTML-страницы в окне и обслуживаете истории сессий HTML-страниц, отображаемых в браузере в течение сессии. Объекты этой среды, следовательно, обязаны иметь возможность манипулировать страницами, окнами и историей.
По контрасту, в серверной среде Вы работаете с ресурсами сервера. Например, Вы можете установить соединение с реляционной базой данных, распределить информацию между пользователями приложения или манипулировать файловой системой сервера. Объекты этой среды обязаны иметь возможность манипулировать реляционной БД и файловой системой сервера.
Кроме того, HTML-страница не отображается на сервере. Она запрашивается на сервере для отображения на клиенте. Запрошенная страница может содержать клиентский JavaScript. Если запрошенная страница является частью приложения JavaScript, сервер может генерировать эту страницу "на лету".
При разработке приложения JavaScript помните о разнице между клиентской и серверной платформами. Различия показаны в следующей таблице.
Обычно имеются разные пути распределения приложения между сервером и клиентом. Некоторые задачи могут выполняться только на клиенте или только на сервере; другие могут выполняться на любом из них. Хотя нет какого-то определённого способа определить, что и где делать, Вы может следовать следующим общим правилам:
Основное правило - использовать клиентский процессинг (тэг SCRIPT
)
для следующих задач:
Использовать серверный процессинг (тэг SERVER
)
для следующих задач:
Служба JavaScript Session Management Service предоставляет объекты для сохранения информации, а клиентский JavaScript преходящ. Клиентские объекты существуют, пока пользователь имеет доступ к странице. Серверы могут объединять информацию от многих клиентов и многих приложений и могут сохранять большие объёмы данных в базе данных. Важно помнить обо всех этих характеристиках при распределении функциональности между клиентом и сервером.
После того как Вы установили и стартовали приложение JavaScript, пользователь
может получить к нему доступ.
Базовые процедуры таковы:
SERVER
, из
исходного кода HTML,
создавая HTML-страницу на основе этих байт-кодов и иного HTML, имеющегося в
оригинале. О том, как влиять на процесс конструирования страницы,
см. в разделе "Конструирование HTML-Страницы".Рисунок 5.1 иллюстрирует это процесс.
Конечно, пользователь обязан иметь Netscape Navigator (или иной браузер с возможностью выполнения JavaScript), чтобы клиент мог интерпретировать операторы клиентского JavaScript. Аналогично, если Вы создаёте страницу, содержащую серверный JavaScript, он должен быть установлен на Netscape-сервере, чтобы нормально функционировать.
Например, предположим, клиент запрашивает страницу с таким исходным кодом:
<html>
<head> <title> Add New
Customer </title> </head>
<body text="#FFFF00" bgcolor="#C0C0C0" background="blue_marble.gif">
<img src="billlog2.gif">
<br>
<server>
if ( project.lock() ) {
project.lastID = 1 + project.lastID;
client.customerID = project.lastID;
project.unlock();
}
</server>
<h1>Add a New Customer </h1>
<p>Note: <b>All</b> fields are required for the new customer
<form
method="post" action="add.html"></p>
<p>ID:
<br>
<server>write("<STRONG><FONT COLOR=\"#00FF00\">" +
project.lastID + "</FONT></STRONG>");</server>
<!-- другие операторы html -->
</body>
</html>
При доступе к этой странице машина выполнения выполняет
на сервере код, ассоциированный с тэгами SERVER
. (Этот код выделен
жирным шрифтом.) Если ID нового потребителя 42, сервер высылает клиенту для
отображения такую HTML-страницу:
<html>
<head> <title> Add New
Customer </title> </head>
<body text="#FFFF00" bgcolor="#C0C0C0" background="blue_marble.gif">
<img src="billlog2.gif">
<br>
<h1>Add a New Customer
</h1>
<p>Note: <b>All</b> fields are required for the new customer
<form method="post" action="add.html"></p>
<p>ID:
<br><STRONG><FONT COLOR="#00FF00">42</FONT></STRONG>
<!-- другие операторы html -->
</body>
</html>
И клиентский, и серверный JavaScript реализуют язык JavaScript. Но каждый при
этом добавляет специфические объекты и функции для работы в клиентской или
серверной среде. Например, клиентский
JavaScript включает объект form
для представления формы на HTML-странице,
а серверный
JavaScript включает объект database
для соединения с внешней
реляционной БД.
В книге Клиентский JavaScript. Руководство. детально рассматривается ядро языка JavaScript и дополнительная специфика клиентского JavaScript.
ECMA, Европейская организация стандартизации систем информации и коммуникаций,
выпустила стандарт ECMA-262 языка JavaScript. Вы можете загрузить эту
спецификацию с сайта ECMA по адресу
http://www.ecma.ch
.
Как указано в книге
Серверный JavaScript. Справочник.
, Вы можете
использовать свойство prototype
многих классов, чтобы добавлять
новые свойства в класс и во все его экземпляры. Как описано в разделе "Классы
и Объекты", серверный JavaScript добавляет несколько классов и
предопределённых объектов. В новых классах, имеющих свойство prototype
,
оно работает в серверном JavaScript точно так же, как и в клиентском JavaScript.
Вы можете использовать свойство prototype
для добавления новых
свойств в классы Blob
,
Connection
, Cursor
, DbPool
, File
, Lock
,
Resultset
, SendMail
и Stproc
. Кроме того,
Вы можете использовать свойство prototype
класса DbBuiltin
для добавления свойств в предопределённый объект database
. Обратите
внимание, что Вы не можете создать экземпляр класса
DbBuiltin
; вместо этого Вы используете объект database
,
предоставляемый машиной выполнения JavaScript.
Вы не можете использовать prototype
с
объектами client
,
project
, request
и server
.
Так же, как и в клиентском JavaScript, Вы можете использовать свойство prototype
для любого класса, который Вы определяете в своём приложении.
Помните, что все приложения JavaScript на сервере
работают в одной среде. Вот почему Вы можете распределять информацию между
клиентами и приложениями.
Следствием этого, однако, является то, что при использовании свойства prototype
для добавления нового свойства в любой серверный класс, добавленный языком JavaScript,
новое свойство доступно всем приложениям, работающим на сервере, а не только
приложению, в котором это свойство было добавлено. Это даёт возможность легко
добавлять функциональность всем приложениям JavaScript
на Вашем сервере.
В противоположность этому, если Вы добавляете свойство в класс, который Вы определили в своём приложении, это свойство доступно только в том приложении, где оно было создано.
Вам необходимо знать, как компилятор приложений JavaScript распознаёт клиентский и серверный JavaScript в HTML-файле.
Операторы клиентского JavaScript могут появляться в следующих ситуациях:
SCRIPT
SCRIPT
О деталях см. книгу Клиентский JavaScript. Руководство .
Операторы серверного JavaScript могут появляться в следующих ситуациях:
SERVER
Заметьте, что Вы не можете специфицировать оператор серверного JavaScript как обработчик события. Дополнительно см. "Внедрение JavaScript в HTML".
Возможности LiveConnect ядра языка JavaScript работают на сервере иначе, чем на клиенте. См. дополнительно Главу 14, "LiveConnect. Обзор.".
JavaScript предоставляет дополнительную функциональность без использования объектов. Вы получаете доступ к этой функциональности через функции, не ассоциированные с каким-либо объектом (глобальные функции). Ядро языка JavaScript имеет глобальные функции, описанные в следующей таблице (также как и другие функции, описанные в документации Ядра JavaScript).
Серверный JavaScript добавляет глобальные функции, описанные в следующей таблице.
Функция | Описание |
---|---|
write
|
Добавляет операторы к генерируемой клиентской HTML-странице. (См. "Генерация HTML".) |
flush
|
Очищает буфер вывода. (См. "Очистка Буфера Вывода".) |
redirect
|
Перенаправляет клиента по специфицированному URL. (См. "Переход к Новому Клиентскому Запросу".) |
getOptionValue
|
Получает значения отдельных опций в элементе HTML-формы |
getOptionValueCount
|
Получает количество опций в элементе HTML-формы |
debug
|
Выводит значения выражений в окне (фрэйме) трассировки. (См. "Использование Функции debug".) |
addClient
|
Присоединяет клиентскую информацию к URL. (См. "Присоединение client-Свойств к URL Вручную".) |
registerCFunction
|
Регистрирует внешнюю функцию для использования в серверном JavaScript. (См. "Регистрация Внешних Функций/Native Functions".) |
callC
|
Вызывает внешнюю функцию. (См. "Использование Внешних Функций в JavaScript".) |
deleteResponseHeader
|
Удаляет информацию из "шапки" ответа, высылаемого клиенту. (См. "Манипуляции с Запросом и Ответом".) |
addResponseHeader
|
Добавляет новую информацию в "шапку" ответа, высылаемого клиенту. (См. "Манипуляции с Запросом и Ответом".) |
ssjs_getClientID
|
Возвращает идентификатор для |
ssjs_generateClientID
|
Возвращает идентификатор, который Вы можете использовать для уникального
специфицирования объекта |
ssjs_getCGIVariable
|
Возвращает значение специфицированной переменной окружения CGI. (См. "Доступ к Переменным CGI".) |
Для поддержания различных задач, выполняемых на каждой стороне, JavaScript имеет классы и предопределённые объекты, которые работают на клиенте, но не на сервере, и другие классы и предопределённые объекты, которые работают на сервере, но не на клиенте.
Важно!Названия этих объектов зарезервированы для JavaScript. Не создавайте Ваши собственные объекты, используя эти имена.
Ядро языка JavaScript предоставляет классы, описанные в следующей таблице. Детальную информацию обо всех этих объектах см. в книге Серверный JavaScript. Справочник .
Серверный JavaScript включает классы ядра, но не классы клиентского JavaScript. Серверный JavaScript имеет свой набор дополнительных классов для поддержки необходимой функциональности, как показано в следующей таблице.
Класс |
Описание
|
Connection
| Одиночное соединение с БД из пула соединений. (См. "Отдельные Соединения с БД").
|
Cursor
| Курсор БД. (См. "Манипуляции с Результатами Выполнения Запроса с Помощью Курсоров").
|
DbPool
| Пул соединений с базами данных. (См. "Пулы Соединений с Базами Данных").
|
Stproc
| Хранимая процедура БД. (См. "Вызов Хранимых Процедур").
|
Resultset
| Представляет информацию, возвращаемую хранимой процедурой БД. (См. "Вызов Хранимых Процедур".)
|
File
| Предоставляет доступ к файловой системе сервера. (См. "Служба Файловой Системы".)
|
Lock
| Предоставляет функциональность для безопасного совместного использования/sharing данных запросами, клиентами и приложениями. (См. "Безопасное Совместное Использование Объектов с Блокировкой".)
|
SendMail
| Предоставляет функциональность для отправки электронной почты из вашего приложения JavaScript. (См. "Почтовая Служба".) |
---|
Кроме того, серверный JavaScript имеет предопределённые объекты, описанные в следующей таблице. Эти объекты доступны для каждого HTTP-запроса. Вы не можете создать дополнительные экземпляры какого-либо из этих объектов.
Объект |
Описание
|
database
| Соединение с базой данных. (См. "Соединение. Подходы.")
|
client
| Инкапсулирует информацию о паре клиент/приложение, позволяя хранить эту информацию дольше, чем в течение одного HTTP-запроса. (См. "Объект client.")
|
project
| Инкапсулирует информацию о приложении, которая хранится, пока приложение не прекратит работу на сервере. (См. "Объект project".)
|
request
| Инкапсулирует информацию об отдельном HTTP-запросе. (См. "Объект request".)
|
server
| Инкапсулирует глобальную информацию о сервере, которая хранится, пока сервер не остановится. (См. "Объект server".) |
---|
Есть два способа встроить операторы серверного JavaScript в HTML-страницу:
SERVER
.
Используйте этот тэг для размещения в нём одиночного оператора JavaScript
или нескольких операторов. Оператор расположен между тэгами <SERVER>
и </SERVER>
.
Вы можете перемежать
тэги SERVER
полными операторами HTML.
Никогда не помещайте тэг SERVER
между открывающей (<
)
и закрывающей
(>
) угловыми скобками тэга HTML. (См. "Тэг SERVER").
Также не используйте тэг <SCRIPT>
между тэгами <SERVER>
и </SERVER>
.
Используйте этот символ для включения выражений JavaScript внутрь тэгов HTML,
обычно для генерирования атрибута или значения атрибута
HTML на базе значений JavaScript. Эта техника используется внутри таких тэгов,
как якоря, изображения или тэги элементов формы, например, для предоставления
значения атрибута HREF
якоря.
Если Вы внедряете серверный JavaScript в HTML-страницу, машина выполнения JavaScript
на сервере выполняет обнаруженные ею операторы при процессинге (обработке)
страницы. Большинство операторов выполняют какие-либо операции на сервере, такие
как открытие соединения с БД или блокировка совместно используемого объекта.
Однако,
если Вы используете функцию write
в тэге SERVER
или
заключаете операторы в обратные кавычки, машина выполнения динамически
генерирует новый HTML для модифицирования страницы, высылаемой клиенту.
Тэг SERVER
это наиболее распространённый способ внедрения
серверного JavaScript в HTML-страницу.
Вы можете использовать тэг SERVER
в любой ситуации; обычно, однако,
вместо него используются обратные кавычки, если Вы генерируете имена или
значения атрибутов для HTML-страницы.
Большая часть операторов между тэгами <SERVER>
и </SERVER>
не появляется на HTML-странице, высылаемой клиенту. Эти операторы выполняются на
сервере. Однако вывод вызовов функции write
появляется в
результирующем HTML.
Следующая выдержка из приложения Hello World иллюстрирует эти варианты:
<P>This time you are
<SERVER>
write(request.newname);
client.oldname = request.newname;
</SERVER>
<h3>Enter your name</h3>
Получив данный участок кода, машина выполнения генерирует HTML
на базе значения request.newname
в операторе write
. Во
втором операторе она просто выполняет операцию JavaScript, присваивая значение request.newname
свойству client.oldname
. Она не генерирует никакого HTML. Итак,
если request.newname
будет "Mr. Ed," машина выполнения генерирует
из предыдущего отрывка следующий HTML:
<P>This time you are
Mr. Ed
<h3>Enter your name</h3>
Используйте обратные кавычки (`
) для выделения выражений серверного JavaScript
как заместителей для имён атрибутов или значений атрибутов HTML. JavaScript,
внедрённый в HTML с помощью обратных кавычек, автоматически генерирует
HTML; Вам не нужно использовать write
.
В целом тэги HTML имеют форму:
<TAG ATTRIB="value" [...ATTRIB="value"]>
где
ATTRIB
это атрибут, а "
value
"
это его значение. Значение в угловых скобках означает, что
допускается любое количество пар атрибут/значение.
Если в обратные кавычки заключено выражение JavaScript, используемое как значение атрибута, машина выполнения JavaScript автоматически добавляет знак кавычки вокруг всего значения. Вы сами не вводите знаки кавычек, хотя Вам это может понадобиться для разграничения строковых литералов выражения, как в следующем примере. Машина выполнения не делает это для имён атрибутов, поскольку не предполагается заключение имён атрибутов в кавычки.
Например, рассмотри следующую строку из образца-приложения Hangman:
<IMG SRC=`"images\hang" + client.num_misses + ".gif"`>
Эта строка динамически генерирует имя изображения на
основе значения client.num_misses
. Обратные кавычки обрамляют
выражение JavaScript, конкатенирующее строку "images\hang"
и
целочисленное значение client.num_misses
и строку ".gif"
,
давая строку типа "images\hang0.gif"
. Результатом будет HTML, такой
как
<IMG SRC="images\hang0.gif">
Порядок ввода кавычек является критичным. Сначала идёт обратная кавычка,
указывая, что следующее значение является выражением JavaScript, состоящим из
строки ("images\hang"
), соединяемой с целым числом (client.num_misses
)
и с другой строкой (".gif"
).
JavaScript конвертирует всё выражение до строки и добавляет необходимые знаки
кавычек вокруг значения атрибута.
Вы должны внимательно использовать знаки двойных
кавычек внутри обратных кавычек, поскольку содержащееся внутри них значение
интерпретируется как литерал. Поэтому не окружайте выражения JavaScript, которые
необходимо вычислить, знаками кавычек. Например, если значение свойства client.val
будет NetHead, то данный оператор:
<A NAME=`client.val`>
<A NAME="NetHead">
<A NAME=`"client.val"`>
<A NAME="client.val">
В качестве другого примера приведём два атрибута тэга ANCHOR
- HREF
и
NAME
. HREF
делает тэг гиперссылкой, а NAME
делает его именованным якорем. Следующие операторы используют переменную choice
для установки свойств
attrib
и val
объекта client
и создают
затем гиперссылку/hyperlink или цель/target, в зависимости от значений:
<SERVER>
if (choice == "link") {
client.attrib
= "HREF";
client.val = "http://www.netscape.com";
}
if (choice == "target") {
client.attrib = "NAME";
client.val = "NetHead";
}
</SERVER>
<A `client.attrib`=`client.val`>Netscape
Communications</A>
Если значением choice
будет "link"
, результат будет:
<A HREF="http://home.netscape.com">Netscape Communications</A>
Если значением choice
будет "target"
, результат будет:
<A NAME="NetHead">Netscape Communications</A>
В большинстве случаев ясно, когда использовать тэг SERVER
,
а когда - обратные кавычки. Иногда, однако можно достичь того же результата
другим путём ("Мы пойдём..."). В общем, лучше использовать обратные кавычки для
внедрения значений JavaScript в тэги HTML, а в других случаях - тэг SERVER
.
<IMG SRC=`"images\hang" + client.num_misses + ".gif"`>
<SERVER>
write("<IMG SRC=\"images\hang");
write(client.num_misses);
write(".gif\">");
</SERVER>
Обратите внимание, что обратная наклонная черта (backslash) даёт возможность ввести знак кавычки внутри литеральной строки. Хотя результирующий HTML - тот же самый, в этом случае обратные кавычки предпочтительнее, поскольку исходник легче читать и редактировать.
В разделе "Обзор Процессинга Времени Выполнения" показано, что происходит на этапе прогона, если пользователь выполняет доступ к странице приложения JavaScript. В данном разделе детально рассматриваются этапы этого процесса со 2 по 4, чтобы Вы смогли лучше понять, что происходит на каждом этапе. Это описание предоставляет контекст для понимания того, что Вам нужно делать на клиенте и сервере.
При работе с приложениями JavaScript важно помнить об асинхронной природе процессов Web. Приложения JavaScript разрабатываются для использования многими пользователями одновременно. Машина выполнения JavaScript на сервере обрабатывает запросы нескольких пользователей по мере их поступления и выполняет их в порядке поступления.
В отличие от традиционного приложения, которое запускается отдельным пользователем на отдельной машине, Ваше приложение обязано поддерживать одновременный доступ нескольких пользователей. Фактически, поскольку каждый фрэйм (кадр) HTML-документа из нескольких фрэймов генерирует свой собственный запрос/request, для машины выполнения может оказаться, что запрос одного пользователя является множественным запросом.
HTTP (Hypertext Transfer Protocol) это протокол, по
которому HTML-страница пересылается клиенту. Этот протокол является stateless\бесстатусным,
то есть информация не сохраняется в период между запросами.
В общем, любая информация, необходимая для обработки HTTP-запроса, должна
пересылаться вместе с этим запросом.
Это создаёт проблемы для многих приложений. Как использовать информацию
одновременно различными пользователями приложения или даже различными запросами
одного пользователя? Служба JavaScript Session Management
Service была разработана для того, чтобы помочь разрешить эту проблему. Детально
эта служба рассматривается в Главе 6, "Session Management Service."
В данный момент просто помните, что машина выполнения автоматически обслуживает
объекты client
, server
,
project
и request
.
Если Netscape-сервер получает клиентский запрос на страницу приложения, он сначала выполняет авторизацию (идентификацию). Этот шаг является частью базовых функций администрирования сервера. Если попытка авторизации запроса не удалась, последующие шаги не выполняются. Если запрос получил авторизацию сервера, машина выполнения JavaScript продолжает работу. Она выполняет следующие шаги, описанные в последующих разделах:
Инициализируются встроенные свойства объекта request
,
такие как IP-адрес и элементы формы, ассоциированные с данным request. Если URL
запроса специфицирует другие свойства, они инициализируются для объекта request
,
как описано в разделе "Кодирование Информации в URL".
Если объект client
уже существует, машина
выполнения запрашивает его на основе специфицированной техники обслуживания
клиента. (См. "Техника Обслуживания Объекта client").
Если объект client
не существует, машина выполнения конструирует
новый объект без свойств.
Вы не можете предвидеть, в каком порядке эти объекты конструируются.
Когда Вы компилировали исходный код JavaScript, исходник включал HTML-страницы с операторами серверного JavaScript. Главной задачей машины выполнения является конструирование из одной из этих исходных страниц HTML-страницы, содержащей только HTML и операторы клиентского JavaScript. При создании этой HTML-страницы машина выполнения сохраняет её части в области памяти, называемой буфером, пока не придёт время отправки буферизованного содержимого клиенту.
Этот шаг выполняется для каждого участка кода исходной страницы. Детали процесса выполнения различных серверных операторов рассматриваются далее в этом учебнике. Дополнительно см. "Конструирование HTML-Страницы".
Для данного запроса/request машина выполнения выполняет этот шаг, пока не произойдёт одно из следующих событий:
В этой ситуации машина выполняет шаги 4 и 5 и возвращается к выполнению шага 3 с очищенным буфером, продолжая выполнение того же запроса. (Шаг 4 исполняется только один раз, даже если шаги 3 и 5 повторяются).
flush
.В этой ситуации машина выполняет шаги 4 и 5 и возвращается к выполнению шага 3 с очищенным буфером, продолжая выполнять тот же самый запрос. (Шаг 4 исполняется только один раз, даже если шаги 3 и 5 повторяются).
redirect
.
В этой ситуации машина выполнения завершает данный запрос, выполняя шаги с 4
по 6. Она игнорирует любые вхождения после функции redirect
в
исходном файле и стартует новый запрос для страницы, специфицированной в
вызове redirect
.
В этой ситуации машина завершает данный запрос, выполняя шаги с 4 по 6.
Машина выполнения сохраняет свойства объекта client
непосредственно перед первой отправкой части HTML-страницы клиенту. Она
сохраняет эти свойства только один раз. Машина выполнения может повторять шаги 3
и 5, но не может повторить данный шаг.
Машина выполнения сохраняет свойства в этот момент, чтобы
поддерживать один из видов техники обслуживания объекта client
.
Например, схема кодирования клиентского URL высылает свойства client'
а
в шапке/header HTML-файла. Поскольку шапка высылается как первая часть файла,
свойства client'
а обязаны быть затем
высланы.
Следовательно, Вы должны учитывать, где в Вашем
файле-источнике устанавливаются свойства client'
а.
Вы всегда должны изменять свойства client'
а
в файле до любого вызова redirect
или flush
и до
генерирования 64KB HTML-вывода.
Если Вы изменяете значения свойств объекта client
в коде после того как HTML был выслан клиенту, эти изменения будут действовать
для оставшейся части клиентского запроса, но затем будут отменены. Отсюда:
следующий клиентский запрос не получит эти значения свойств; он получит
значения, действовавшие в тот момент, когда содержимое было в первый раз
отправлено клиенту. Например,
ваш код содержит такие операторы:
<HTML>
<P>The current customer is
<SERVER>
client.customerName = "Mr. Ed";
write(client.customerName);
client.customerName = "Mr. Bill";
</SERVER>
<P>The current customer really is
<SERVER>
write(client.customerName);
</SERVER>
</HTML>
Эта серия операторов даст в результате такой HTML, отправляемый клиенту:
<P>The current customer is Mr. Ed
<P>The current customer really is
Mr. Bill
Теперь, когда появится следующий клиентский запрос,
значение свойства
client.customerName
будет "Mr. Bill". Этот очень похожий набор
операторов даст в результате тот же HTML:
<HTML>
<P>The current customer is
<SERVER>
client.customerName = "Mr. Ed";
write(client.customerName);
flush();
client.customerName = "Mr. Bill";
</SERVER>
<P>The current customer really is
<SERVER>
write(client.customerName);
</SERVER>
</HTML>
Однако при появлении следующего клиентского запроса значение client.customerName
будет "Mr. Ed"; а не "Mr. Bill".
Дополнительно см. "Техника Обслуживания Объекта client".
Сервер отсылает содержимое страницы клиенту. Для страниц без операторов серверного JavaScript сервер просто передаёт HTML клиенту. Для других страниц - машина выполнения реализует логику приложения для конструирования HTML и затем высылает сгенерированную страницу клиенту.
Машина выполнения разрушает объект request
,
сконструированный для данного клиентского запроса. Она сохраняет значения
объекта client
и разрушает физический объект
JavaScript. Она не разрушает объекты project
или server
.
Когда Вы компилируете приложение JavaScript, исходники состоят из HTML-страниц, содержащих операторы серверного JavaScript, и, возможно, HTML-страницы, не содержащие операторов серверного JavaScript. Если пользователь получает доступ к странице, которая не содержит серверных операторов, сервер высылает страницу обратно, как и любую другую HTML-страницу. Если пользователь получает доступ к странице, которая содержит серверные операторы, машина выполнения на сервере конструирует HTML-страницу для отправки в ответе, используя одну из исходных страниц Вашего приложения.
Машина выполнения сканирует исходную страницу. При обнаружении операторов HTML
клиентского JavaScript
она присоединяет их к создаваемой странице. При обнаружении операторов
серверного JavaScript она выполняет их. Хотя большинство операторов серверного JavaScript
выполняются на сервере,
некоторые влияют на конструируемую страницу. В следующих разделах
рассматриваются три функции: write
, flush
и redirect
,
которые влияют на обрабатываемую HTML-страницу.
Как уже было сказано ранее в этой главе, функция write
генерирует HTML
на основе значения выражения
JavaScript, заданного в качестве аргумента. Например, рассмотрим оператор:
write("<P>Customer Name is:" + project.custname + ".");
В ответ на этот оператор JavaScript генерирует HTML, вставляя тэг параграфа и
некоторый текст,
соединённый со значением свойства custname
объекта project
.
Например, если свойство будет иметь значение "Fred's software company", клиент
получит следующий HTML:
<P>Customer Name is: Fred's software company.
Как кажется клиенту, это нормальный HTML. Однако он в действительности динамически сгенерирован машиной выполнения JavaScript.
Для повышения производительности, JavaScript буферизует
конструируемую им
HTML-страницу. Функция flush
сразу высылает данные из внутреннего
буфера клиенту. Если Вы явно не вызываете функцию flush
, JavaScript
высылает данные клиенту после создания каждых 64KB содержимого конструируемой HTML-страницы.
Не путайте функцию flush
с методом flush
класса File
. (Об
использовании класса File
для ввода и вывода в файл см. "Служба
Файловой Системы").
Вы можете использовать flush
для управления временем переноса
данных клиенту. Например, Вы можете очищать буфер до операции, создающей
задержку/delay, такой как запрос к базе данных.
Также, если запрос к БД запрашивает большое количество рядов, очистка буфера
каждый раз после получения нескольких рядов предотвращает паузы при отображении
данных.
ПРИМЕЧАНИЕ: Если Вы используете клиентские куки для обслуживания свойств объекта
client
, Вы обязаны делать все изменения объектаclient
до очистки буфера. Дополнительно см. "Техника Обслуживания Объекта client".
Следующий фрагмент кода показывает, как используется flush
.
Предположим, Ваше приложение должно выполнить некоторые действия с каждым
потребителем/customer в Вашей БД потребителей. Если потребителей много, процесс
может затянуться. Поэтому, для того чтобы пользователь не ждал у застывшего
экрана, Ваше приложение может высылать вывод клиенту до начала обработки и затем
вновь - после конца обработки каждого ряда. Для этого Вы должны использовать
примерно такой код:
flush();
conn.beginTransaction();
cursor = conn.cursor ("SELECT * FROM CUSTOMER", true);
while ( cursor.next() ) {
// ... обработка ряда ...
flush();
}
conn.commitTransaction();
cursor.close();
Функция redirect
прерывает текущий клиентский запрос и стартует
новый по специфицированному URL. Например, у вас имеется оператор:
redirect("http://www.royalairways.com/apps/page2.html");
Когда машина выполняет это оператор, она прерывает текущий запрос. Машина
выполнения не продолжает обработку страницы-оригинала. Следовательно любые
операторы HTML или JavaScript, идущие в оригинальной странице после вызова redirect
,
будут утеряны. Клиент сразу загрузит указанную страницу, отбросив предыдущее
содержимое.
Параметром для redirect
может быть любой оператор серверного JavaScript,
вычисляемый до URL. Таким образом, Вы можете динамически генерировать URL,
используемый в redirect
. Например,
если страница определяет переменную choice
, Вы можете перенаправить
клиента на страницу в зависимости от значения choice
таким образом:
redirect ("http://www.royalairways.com/apps/page"
+ choice + ".html");
Если Вам нужно удостовериться, что текущие свойства client'а
доступны в новом запросе и что Вы используете один из видов техники обслуживания
объекта client
на основе URL,
Вы должны кодировать свойства в URL, передаваемом Вами в redirect
.
О том, как это сделать, см. "Присоединение
Свойств client'а к URL Вручную".
В целом свойства объекта request
и
переменные верхнего уровня JavaScript существуют только в течение одиночного
клиентского запроса. Если Вы выполняете перенаправление на новую страницу, Вам
может понадобиться сохранить некоторую информацию для нескольких запросов. Вы
можете сделать это, присоединив имена и значения свойств к URL, как описано в
разделе
"Кодирование Информации в URL".
Как и большинство других web-серверов, серверы Netscape устанавливают значения для определённого набора переменных окружения, называемых CGI-переменными, при установке контекста для запуска CGI-скрипта. Предполагается, что создатели CGI-скриптов могут использовать эти переменные в своих скриптах.
По контрасту, Netscape web-серверы не устанавливают отдельного окружения для приложений серверного JavaScript. Тем не менее, некоторая часть информации, обычно устанавливаемой в CGI-переменных, может использоваться в приложениях JavaScript. Машина выполнения предоставляет несколько механизмов для доступа к этой информации:
request
ssjs_getCGIVariable
для доступа к
некоторым CGI-переменным и другим переменным окруженияhttpHeader
объекта request
для доступа к свойствам шапки клиентского запроса
В следующей таблице перечислены свойства объекта
request
, соответствующие CGI-переменным. Дополнительно об этих
свойствах и об объекте request
в целом см.
"Объект request".
request
Серверная функция ssjs_getCGIVariable
даёт
Вам доступ к переменным окружения, установленным в серверном процессе, включая CGI-переменные,
перечисленные в следующей таблице.
ssjs_getCGIVariable
Здесь приведён синтаксис ssjs_getCGIVariable
:
value = ssjs_getCGIVariable("name");
Этот оператор устанавливает в переменную value
значение
CGI-переменной name
.
Если предоставленный вами аргумент не является одной из CGI-переменных,
перечисленных в
Таблице 5.8,
машина выполнения ищет переменную окружения с этим именем в среде сервера. Если
она найдена,
машина выполнения возвращает значение; иначе, возвращает null. Например,
следующий код присваивает значение стандартной переменной окружения CLASSPATH
переменной JavaScript
classpath
:
classpath = ssjs_getCGIVariable("CLASSPATH");
Метод httpHeader
объекта request
возвращает шапку/header
текущего клиентского запроса. Для CGI-скрипта Netscape web-серверы устанавливают CGI-переменные
для некоторой информации в шапке. Для приложений JavaScript Вы получаете эту
информацию непосредственно из шапки.
Таблица 5.9 показывает информацию, доступную как
переменные CGI в среде CGI,
но как свойства шапки - в серверном JavaScript. В свойствах шапки символы
подчёркивания в имени
CGI-переменной (_) заменяются на тире (-); например, CGI-переменная
CONTENT_LENGTH
соответствует свойству шапки content-length
.
Дополнительно о манипулировании клиентской "шапкой" см. "Манипуляции с Запросом и Ответом".
В таблице даны CGI-переменные, не поддерживаемые серверным JavaScript, которые не могут быть применены при запуске приложений JavaScript.
Переменная | Описание |
---|---|
GATEWAY_INTERFACE
|
Версия CGI, запущенная на сервере. Не применяется к приложениям JavaScript. |
SERVER_SOFTWARE
|
Тип запущенного сервера. Недоступна для приложений JavaScript. |
Нередко Вашим приложениям JavaScript нужно передать информацию либо с сервера
клиенту, либо с клиента на сервер. Например, когда пользователь в первый раз
выполняет доступ к приложению videoapp
, оно динамически генерирует
список категорий видео-файлов из текущего содержимого БД. Эта информация,
генерируемая на сервере, должна быть передана обратно клиенту. И наоборот, когда
пользователь щёлкает на категории из этого списка, выбор пользователя должен
быть передан обратно на сервер, чтобы он мог сгенерировать набор файлов.
Есть несколько способов отправки информации с клиента на сервер:
request
для каждого значения в HTML-форме.
(См. "Доступ к Значениям Формы")client
,
Вы можете модифицировать URL, отправленный серверу, чтобы включить значения
свойств объектов client
и request
. (См. "Кодирование
Информации в URL")client
и
request
. (См. "Использование Кук")httpHeader
объекта request
для манипулирования шапкой и, возможно, телом запроса. (См. "Манипуляции
с Запросом и Ответом").Формы это альфа и омега приложений на JavaScript. Вы используете такие элементы формы как текстовые поля и радио-кнопки в качестве первичного механизма переноса данных с клиента на сервер. Когда пользователь щёлкает на кнопке Submit, браузер отправляет значения, введённые форму, на сервер для обработки.
Атрибут ACTION
тэга FORM
определяет приложение, которому отправляются значения. Для того чтобы отправить
информацию приложению на сервер,
используйте URL приложения как значение атрибута ACTION
.
Если документ, содержащий форму, является скомпилированной
частью того же самого приложения,
Вы можете просто предоставить имя страницы вместо полного URL. Например, вот тэг FORM
из приложения-примера Hangman:
<FORM METHOD="post" ACTION="hangman.html">
Формы, отправляемые приложениям на серверном JavaScript, могут использовать get
или post
в качестве значения атрибута METHOD
.
ПРИМЕЧАНИЕ: Приложения на серверном JavaScript не поддерживают автоматическую выгрузку файлов. То есть, если специфицированная action это страница в приложении JavaScript, Вы отправляете элемент
INPUT
с типомTYPE="file"
, Ваше приложение обязано само обработать этот файл, как описано в разделе "Манипуляции с Запросом и Ответом".
Каждый элемент ввода HTML-формы соответствует свойству
объекта
request
. Имя свойства специфицируется атрибутом NAME
элемента формы. Например, следующий HTML создаёт свойство объекта request
под названием
guess
, которое принимает одиночный символ в текстовом поле. Вы
обращаетесь к этому свойству в серверном JavaScript как к request.guess
.
<FORM METHOD="post" ACTION="hangman.html">
<P>
What is your guess?
<INPUT TYPE="text" NAME="guess" SIZE="1">
Элемент SELECT
, дающий возможность множественного выбора, требует
особого обращения, поскольку это единственное свойство, которое может иметь
несколько значений. Вы можете использовать функцию getOptionValue
для получения значений выбранных опций в списке множественного выбора.
Дополнительно см. "Использование Списков Select".
Информацию об объекте request
см. в разделе "Объект
request".
Если Вы хотите обработать данные сначала на стороне клиента, Вы должны создать функцию клиентского JavaScript для выполнения обработки значений элементов формы и передать затем вывод клиентской функции элементу формы. Вы можете скрыть/hide этот элемент, чтобы он не отображался пользователю, если Вы хотите выполнить клиентский препроцессинг.
Например, у Вас имеется функция клиентского JavaScript под
названием
calc
, выполняющая расчёт на основе пользовательского ввода. Вы
хотите передать результат работы этой функции Вашему приложению для дальнейшей
обработки. Сначала Вам нужно определить скрытый элемент формы для результата:
<INPUT TYPE="hidden" NAME="result" SIZE=5>
Затем Вам нужно создать обработчик события onClick
для кнопки Submit,
который назначает вывод функции в скрытый элемент:
<INPUT TYPE="submit" VALUE="Submit"
onClick="this.form.result.value=calc(this.form)">
Значение элемента result
отправляется вместе с другими значениями
элементов формы. Обратиться к этому значению в приложении можно request.result
.
HTML-тэг SELECT
, используемый с атрибутом MULTIPLE
,
даёт возможность ассоциировать несколько значений с одним элементом формы. Если
Вашему приложению нужны списки с возможностью выбора нескольких опций, Вы
используете функцию getOptionValue
для получения значений в JavaScript.
Синтаксис getOptionValue
таков:
itemValue = getOptionValue(name, index)
Здесь name
это строка, специфицированная как атрибут NAME
тэга
SELECT
, а index
это порядковый индекс выбранной опции,
начиная с 0.
Функция getOptionValue
возвращает значение выбранного элемента, как
специфицировано ассоциированным тэгом OPTION
.
Функция getOptionValueCount
возвращает количество опций (специфицированных
тэгами
OPTION
) в списке выбора. Она требует только одного аргумента,
строки, содержащей имя тэга SELECT
.
Например, у Вас имеется следующий элемент:
<SELECT NAME="what-to-wear" MULTIPLE SIZE=8>
<OPTION SELECTED>Jeans
<OPTION>Wool Sweater
<OPTION SELECTED>Sweatshirt
<OPTION SELECTED>Socks
<OPTION>Leather Jacket
<OPTION>Boots
<OPTION>Running Shoes
<OPTION>Cape
</SELECT>
Вы можете обработать ввод из этого select-списка таким образом:
<SERVER>
var i = 0;
var howmany = getOptionValueCount("what-to-wear");
while ( i < howmany ) {
var optionValue =
getOptionValue("what-to-wear", i);
write ("<br>Item #" + i + ": " + optionValue + "\n");
i++;
}
</SERVER>
Если пользователь оставил выбор по умолчанию, скрипт возвратит:
Item #0: Jeans
Item #1: Sweatshirt
Item #2: Socks
Вы можете вручную кодировать свойства объекта request
в URL, по которому выполняется доступ к странице Вашего приложения. При создании URL
используется следующий синтаксис:
URL?varName1=value1[&varName2=value2...]
Здесь URL
это базовый URL, каждое varName
N
это имя свойства,
каждое value
N
это соответствующее
свойству значение (с мнемониками специальных символов). В этой схеме после
базового URL идёт знак вопроса (?
), после которого, в свою очередь,
идут пары имён свойств и их значений. Каждая пара отделяется амперсандом
(&
). Когда машина выполнения на сервере получает результирующий URL
в качестве клиентского запроса, она создаёт свойство объекта request
под названием varName
N
для каждой
переменной.
Например, следующий HTML определяет гиперссылку на страницу, инстанциирующую
свойства объекта request
i
и j
в 1 и 2,
соответственно. Операторы JavaScript в
refpage.html
могут затем обратиться к эти переменным request.i
и
request.j
.
<A HREF="refpage.html?i=1&j=2">Click Here</A>
Вместо использования статической URL-строки, как в предыдущем примере, Вы можете использовать операторы серверного или клиентского JavaScript для динамической генерации URL, кодирующего значения свойств. Например, Ваше приложение может включать страницу:
<HTML>
<HEAD>
<SCRIPT>
function compute () {
// ... заменить подходящими расчётами,
// которые возвращают строку поиска ...
return "?num=25";
}
</SCRIPT>
</HEAD>
<BODY>
<a HREF="refpage.html" onClick="this.search=compute()">
Click here to submit
a value.</a></p>
</BODY>
</HTML>
В данном случае, если пользователь щёлкнет на ссылке,
машина выполнения на клиенте запустит на выполнение обработчик события onClick
.
Этот обработчик устанавливает часть поиска из URL в ссылке в какую-нибудь
строку, возвращённую функцией compute
. Когда машина выполнения на
сервере получит этот запрос, она создаст свойство num
объекта request
и установит его значение в 25.
В качестве второго примера Вы можете добавить свойства объекта request
в URL, созданный в серверном скрипте. Это особенно применимо, если Вы перенаправляете клиентский запрос на новую страницу. Чтобы добавить свойства
объекта request
в серверный скрипт, Вы можете использовать такой
оператор:
<A HREF=`"refpage.html?i=" + escape(i) + "&j=" + escape(j)`>
Click Here</A>
Если вы создаёте URL в операторе серверного JavaScript, свойства объекта client
не добавляются автоматически. Если Вы используете технику на основе URL для
объекта client
, используйте функцию addClient
для
генерирования окончательного URL. В этом примере оператор может быть таким:
<A HREF=`addClient("refpage.html?i=" + escape(i)
+ "&j=" + escape(j))`>Click Here</A>
Об использовании addClient
см. "Присоединение
Свойств Объекта client к URL Вручную".
Функция escape
ядра JavaScript даёт возможность кодировать имена
или значения, присоединённые к
URL, включая специальные символы. Вообще, если приложению необходимо
генерировать имена и значения собственных свойств в URL запроса, Вы должны
использовать escape
, чтобы гарантировать корректную интерпретацию
всех значений. Дополнительно см. книгу
Серверный JavaScript. Справочник
.
Помните, что URL не изменяется, если пользователь перезагружает его, хотя
содержимое страницы может измениться.
Любые свойства, высланные в оригинальном URL, восстанавливают свои значения в URL,
имевшиеся на момент его первой отправки,
независимо от любых возможных изменений, сделанных при обработке. Например, если
пользователь щёлкнул кнопку
Reload для перезагрузки URL в предыдущем примере, i
и j
снова установятся в 1 и 2, соответственно.
Приложение JavaScript сообщается с клиентом через HTML и клиентский JavaScript. Если Вам нужно просто вывести информацию пользователю, нет никаких проблем: Вы создаёте HTML для форматирования этой информации так, как она будет отображаться.
Однако Вам может понадобиться выслать значения непосредственно клиентскому скрипту. Можно сделать это по-разному, включая такие способы:
SCRIPT
или обработчиках событий. (См. "Прямая
Замена")client
или других значений клиенту.
(См. "Использование Кук")deleteResponseHeader
и addResponseHeader
.
(См. "Манипуляции с Запросом и Ответом").
Чтобы отобразить HTML-форму с набором значений по
умолчанию в элементах формы, используйте тэг INPUT
для создания
необходимых элементов формы, замещая выражения серверного JavaScript
атрибутов VALUE
. Например, Вы можете использовать следующий
оператор для отображения элемента text и установки значения по умолчанию на
основе значения переменной client.custname
:
<INPUT TYPE="text" NAME="customerName" SIZE="30"
VALUE=`client.custname`>
Начальным значением этого текстового поля становится значение переменной client.custname
.
Так, если значением client.custname
является Victoria, клиенту
будет выслан такой оператор:
<INPUT TYPE="text" NAME="customerName" SIZE="30" VALUE="Victoria">
Вы может использовать аналогичную технику со скрытыми элементами формы, если не хотите показывать значения пользователю, как в следующем примере:
<INPUT TYPE="hidden" NAME="custID" SIZE=5 VALUE=`client.custID`>
В обоих случаях Вы можете использовать эти значения
клиентского JavaScript в значениях свойств объектов, доступных клиенту. Если эти
два элемента находятся в форме с именем entryForm
,
то значения станут свойствами JavaScript document.entryForm.customerName
и document.entryForm.custID
, соответственно. Вы можете затем
выполнять обработку этих значений на стороне клиента. См. также книгу
Клиентский JavaScript. Руководство
.
Вы можете также использовать серверный JavaScript для
генерирования клиентских скриптов. Эти значения могут использоваться в
последовательности операторов на клиенте. В качестве простого примера Вы можете
инициализировать клиентскую переменную по имени budget
на основе
значения client.amount
таким образом:
<p>The budget is:
<SCRIPT>
<SERVER>
write("var budget = " + client.amount);
</SERVER>
document.write(budget);
</SCRIPT>
Если значение client.amount
равно 50, это
сгенерирует такой JavaScript:
<p>The budget is:
<SCRIPT>
var budget = 50
document.write(budget);
</SCRIPT>
При запуске на клиенте это будет выглядеть так:
The budget is: 50
Куки это механизм, который Вы можете использовать на
клиенте для сохранения информации между запросами. эта информация находится в
файле с названием cookie.txt
(куки-файл), хранящемся на клиентской
машине. Протокол Netscape cookie детально описан в книге
Клиентский JavaScript. Руководство
.
Вы можете использовать куки для отправки информации в обоих направлениях, от
клиента серверу и с сервера клиенту. Куки, высылаемые с клиента, становятся
свойствами объекта
client
или объекта request
. Хотя Вы можете выслать с
сервера клиенту любое строковое значение в качестве куки, простейший метод будет
- отправить свойства объекта
client
.
Если приложение использует технику клиентских кук для работы с объектом client
,
машина выполнения на сервере сохраняет имена и значения свойств объекта client
как куки на клиенте. Об использовании кук для работы с объектом
client
см. раздел "Техника Работы с
Объектом client".
Для свойства объекта client
propName
машина выполнения автоматически создаёт куку с именем NETSCAPE_LIVEWIRE.
propName
,
принимая, что приложение использует технику работы с клиентскими куками. Машина
выполнения кодирует значения свойств так, как это требуется по протоколу кук Netscape
cookie protocol.
Для доступа к этим кукам в клиентском JavaScript Вы можете извлечь эту
информацию путём использования свойства
document.cookie
и такой функции как getSSCookie
, как
показано здесь:
function getSSCookie(name) {
var search = "NETSCAPE_LIVEWIRE." + name + "=";
var retstr = "";
var offset = 0;
var end = 0;
if (document.cookie.length > 0) {
offset = document.cookie.indexOf(search);
if (offset != -1) {
offset += search.length;
end = document.cookie.indexOf(";", offset);
if (end == -1)
end = document.cookie.length;
retstr = unescape(document.cookie.substring(offset, end));
}
}
return(retstr)
}
Функция getSSCookie
не является предопределённой функцией JavaScript.
Если Вам нужна похожая функциональность, Вы обязаны определить её (функцию) в
Вашем приложении.
Чтобы отправленная на сервер информация стала свойством объекта client
,
добавьте куку с именем, имеющим форму NETSCAPE_LIVEWIRE.
propName.
Предположим, Ваше приложение использует технику работы с клиентскими куками, а
машина выполнения на сервере создаёт свойство объекта client
под
названием
propName
для данной куки.
Тогда Вы можете использовать функцию типа следующей:
function setSSCookie (name, value, expire) {
document.cookie =
"NETSCAPE_LIVEWIRE." + name + "="
+ escape(value)
+ ((expire == null) ? "" : ("; expires=" + expire.toGMTString()));
}
Здесь функция setSSCookie
также не является предопределённой
функцией JavaScript. Если Вам необходима аналогичная функциональность, Вы
обязаны определить функцию в Вашем приложении.
Вы можете вызывать эти функции в клиентском JavaScript для получения набора
значений свойств объекта
client
, как в следующем примере:
var value = getSSCookie ("answer");
if (value == "") {
var expires = new Date();
expires.setDate(expires.getDate() + 7);
setSSCookie ("answer", "42", Expires);
}
else
document.write ("The answer is ", value);
Эта группа операторов проверяет, имеется ли свойство объекта client
с названием
answer
. Если нет, код создаёт его и устанавливает значение 42; если
найдено, выводится его значение.
Когда серверу высылается запрос на страницу приложения JavaScript, шапка/header
запроса включает все куки, установленные в данный момент для приложения. Можно
использовать метод request.httpHeader
для доступа к этим кукам из
серверного JavaScript и присвоения их значений серверным переменным.
И наоборот, Вы можете использовать функцию addResponseHeader
для
добавления новых кук в ответ, высылаемый обратно клиенту. Эта функциональность
описана в разделе
"Манипуляция с Запросом и Ответом".
На клиентской стороне Вы можете использовать функцию вроде приведённой здесь для доступа к куке:
function GetCookie (name) {
var arg = name + "=";
var alen = arg.length;
var clen = document.cookie.length;
var i = 0;
while (i < clen) {
var j = i + alen;
if (document.cookie.substring(i, j) == arg) {
var end = document.cookie.indexOf (";", j);
if (end == -1)
end = document.cookie.length;
return unescape(document.cookie.substring(j, end));
}
i = document.cookie.indexOf(" ", i) + 1;
if (i == 0) break;
}
return null;
}
И Вы может использовать функцию типа приведённой ниже для установки куки на клиенте:
function setCookie (name, value, expires, path, domain, secure) {
document.cookie =
name + "="
+ escape(value)
+ ((expires) ? "; expires=" + expires.toGMTString() : "")
+ ((path) ? "; path=" + path : "")
+ ((domain) ? "; domain=" + domain : "")
+ ((secure) ? "; secure" : "");
}
Если путь, специфицированный Вами для куки, находится в Вашем приложении JavaScript, то эта кука будет отправлена в ответ на любой запрос к приложению.
Вы можете использовать эту технику для передачи информации куки между клиентом и
сервером, независимо от вида используемой техники работы с объектом client
.
Серверный JavaScript имеет сборщика мусора, который автоматически освобождает память, выделенную для объекта, более не используемого. В большинстве случаев нет необходимости понимать досконально работу сборщика мусора. Этот раздел даёт обзор сборщика мусора и информацию о том, когда он вызывается.
Этот раздел даёт возможность продвинутым пользователям взглянуть на внутренние процессы JavaScript. Netscape не гарантирует, что эти алгоритмы останутся такими же в последующих релизах.
Пространство объекта в JavaScript состоит из арен. То есть машина выполнения JavaScript размещает набор арен, из которого затем размещает объекты. Если машина выполнения получает запрос на новый объект, она сначала просматривает список свободных арен. Если в списке свободных есть место, машина выделяет его. Иначе машина выполнения выделяет место в текущей используемой арене. Если используются все арены, машина размещает новую арену. Если все объекты арены - мусор, сборщик мусора освобождает арену.
Строка JavaScript обычно размещается как GC-объект. Строка имеет ссылку на байты строки, которая также размещается в куче/heap процесса. Если строковой объект подвергся сборке мусора, байты строки высвобождаются.
Работа сборщика мусора JavaScript основана на пометке и уничтожении. Сборщик не перемещает объекты. Он всегда обрабатывает корневой набор объектов. Этот корневой набор/root set включает в себя стэк JavaScript, объект global для контекста JavaScript и любые объекты JavaScript, которые были явно добавлены в корневой набор. В фазе разметки сборщик мусора помечает все объекты, достижимые из корневого набора. В конечной фазе все непомеченные объекты уничтожаются. Все убранные объекты собираются в список свободных.
Сборка мусора считается необходимой, если количество текущих используемых байтов в 1.5 раза превышает количество байтов, бывших в использовании в конце последней уборки мусора. Машина выполнения проверяет это условие в следующих точках и начинает уборку, если это необходимо:
if
, while
,
вызове функции и т.п.)lw_ForceGarbageCollection
.
Функция ssjs_onError
, если она определена в Вашем приложении,
вызывается в случае ошибки серверного JavaScript, такой как "undefined variable name/имя
переменной не определено". В функции ssjs_onError
Вы можете
делать всё,
что можно делать в функции серверного JavaScript, включая доступ к объектам server
, project
, client
и request
. Вы можете также выполнять перенаправление и вызывать другие функции.
Функция ssjs_onError
имеет следующий
синтаксис:
function ssjs_onError (<message>,<file>,<line number>)
<message>
текст сообщения об ошибке
<line number>
номер строки с ошибкой
Ошибка JavaScript в ходе выполнения функции onError
записывается в log-файл и трассируется (если активна). Функция ssjs_onError
,
однако, не вызывается рекурсивно. Ошибка в функции onError вызывает запись
сообщения в error log,
но не выполняет вызов onError.
function ssjs_onError(msg,file,line)
{
write("<br>\n<hr>")
write("error message: "+msg+"<br>\n")
write("file name: "+file+"<br>\n")
write("line number: "+line+"<br>\n")
write("<hr>")
}
ПРИМЕЧАНИЕ:
Чтобы дать каждой странице её собственную специальную функцию onError, добавьте присвоение ssjs_onError в начале кода страницы. Например:
ssjs_onError = custom_onError;
function custom_onError(msg,file,line)
{
// ...
}
Серверный JavaScript выполняет всё, что ssjs_onError
представляет
во время ошибки.
Вы можете использовать одну функцию ssjs_onError
, которая совместно
используется всеми страницами, либо можете динамически переключаться на другую
функцию onError в любое время, в том числе в начале каждой страницы.
Если два запроса выполняют одну и ту же функцию onError в один момент времени,
они имеют различные среды выполнения, как если бы Вы одновременно выполняли
какую-нибудь другую функцию.
Дата последнего обновления: 29 сентября 1999 г.
© Copyright ╘ 1999 Sun Microsystems, Inc. Некоторая часть Copyright ╘ 1999 Netscape Communications Corp. Все Права Зарезервированы.