В этой главе рассматривается дополнительная функциональность серверного JavaScript, которую Вы можете использовать для отправки e-mail из Вашего приложения, для доступа к файловой системе сервера, подключения внешних библиотек или непосредственного манипулирования клиентскими запросами и клиентскими ответами.
В главе имеются следующие разделы:
Вашему приложению может понадобиться отправить email-сообщение. Для этого Вы
используете экземпляры класса SendMail
. Единственным методом SendMail
является send
, для отправки сообщения,
а errorCode
и errorMessage
служат для интерпретации ошибок.
Например, следующий скрипт отсылает почту в vpg со специфицированной темой/subject и телом сообщения:
<server>
SMName = new SendMail();
SMName.To = "vpg@royalairways.com";
SMName.From = "thisapp@netscape.com";
SMName.Subject = "Here's the information you wanted";
SMName.Body = "sharm, maldives, phuket, coral sea, taveuni, maui,
cocos island, marathon cay, san salvador";
SMName.send();
</server>
В таблице даны свойства класса SendMail
.
Свойства To
и From
необходимы; все остальные свойства - по выбору/optional.
SendMail
Вы можете добавлять к этим свойствам любые другие.
Все свойства класса SendMail
включаются в шапку/header сообщения
при фактической отправке. Например, следующий код отсылает сообщение получателю bill
от vpg
, устанавливая в поле vpg
organization значение Royal Airways.
Отвечает на сообщение от vpgboss
.
mailObj["Reply-to"] = "vpgboss";
mailObj.Organization = "Royal Airways";
mailObj.From = "vpg";
mailObj.To = "bill";
mailObj.send();
Дополнительно о предопределённых полях шапки см. RFC 822, стандарт формата текстовых сообщений Internet.
Класс SendMail
позволяет отправлять простое текстовое почтовое
сообщение или сложное MIME-сообщение. Вы можете также добавить в сообщению
приложение/attachment. Для отправки MIME-сообщения добавьте свойство Content-type
к объекту SendMail
и укажите в нём MIME-тип сообщения.
Например, следующий участок кода отсылает изображение в формате GIF:
<server>
SMName = new SendMail();
SMName.To = "vpg@royalairways.com";
SMName.From = "thisapp@netscape.com";
SMName.Subject = "Here's the image file you wanted";
SMName["Content-type"] = "image/gif";
SMName["Content-Transfer-Encoding"] = "base64";
// В следующем операторе image2.gif обязан быть кодирован с базой 64/base 64.
// Если вы используете uuencode для кодирования GIF-файла, удалите header
// (например, "begin 644 image2.gif")
и замыкающий ("end").
fileObj = new File("/usr/somebody/image2.gif");
openFlag = fileObj.open("r");
if ( openFlag ) {
len = fileObj.getLength();
SMName.Body = fileObj.read(len);
SMName.send();
}
</server>
Некоторые MIME-типы требуют больше информации. Например, если content type это multipart/mixed
,
Вы обязаны также специфицировать сепаратор границ для одного или более различных
наборов данных тела. Например, следующий код отсылает многочастное сообщение,
содержащее две части, каждая из которых является обычным текстом:
<server>
SMName = new SendMail();
SMName.To = "vpg@royalairways.com";
SMName.From = "thisapp@netscape.com";
SMName.Subject = "Here's the information you wanted";
SMName["Content-type"]
= "multipart/mixed; boundary=\"simple boundary\"";
fileObj = new File("/usr/vpg/multi.txt");
openFlag = fileObj.open("r");
if ( openFlag ) {
len = fileObj.getLength();
SMName.Body = fileObj.read(len);
SMName.send();
}
</server>
Вот файл multi.txt
, содержащий многочастное сообщение:
Это место для преамбулы.
Она игнорируется.
Это удобное место для комментария,
предназначенного для читателей, не знакомых с MIME.
--простая граница
Это первая часть тела сообщения.
Это НЕ конец с символом обрыва строки.
--простая граница
Content-Type: text/plain; charset=us-ascii
Это вторая часть тела сообщения.
Это КОНЕЦ с символом обрыва строки.
--простая граница--
Это эпилог. Он также игнорируется.
Вы можете вкладывать друг в друга многочастные сообщения. То есть, если у Вас есть сообщение, content type которого многочастный, Вы можете включить другой многочастное сообщение в его тело. В таких случаях будьте внимательны и убедитесь, штаа каждый вложенный многочастный объект использует разные ограничители.
Детали о MIME-типах см. в RFC 1341 1 , MIME-стандарте. Об отправке почтовых сообщений в JavaScript см. также описание этого класса в книге Серверный JavaScript. Справочник .
JavaScript предоставляет класс File
, который даёт приложению
возможность записывать в файловой системе сервера. Это используется для
генерации постоянных HTML-файлов и хранения информации без использования сервера
БД. Одним из важнейших преимуществ хранения информации в файле вместо JavaScript-объектов
является то, что информация сохраняется даже при отказе сервера.
Соблюдайте осторожность при использовании класса File
. Приложение JavaScript
может читать или записывать файлы везде, где позволяет операционная система, в
том числе, возможно, и в системных файлах. Вы должны быть уверены, что Ваше
приложение не позволяет читать файлы паролей и другую закрытую информацию или
записывать в файлы. Делайте так, чтобы имена файлов, которые Вы передаёте в
методы, не могли быть изменены хакерами.
Например, не используйте свойства объектов client
или
request
в качестве имён файлов, поскольку эти значения могут стать
доступными хакеру через куки или URL. В таких случаях хакер сможет
модифицировать куки или URL, чтобы получить доступ к закрытым файлам.
Исходя из таких же соображений, Navigator не предоставляет автоматического доступа к файловой системе клиентской машины. Если необходимо, пользователь может сохранять информацию непосредственно в клиентской файловой системе, делая соответствующий выбор в меню Navigator'а.
Чтобы создать экземпляр класса File
, используйте стандартный
синтаксис JavaScript для создания объекта:
fileObjectName = new File("path");
Здесь fileObjectName
это имя, по которому Вы обращаетесь к файлу, а path
это полный путь к файлу. Этот path должен быть в формате серверной файловой
системы, а не URL.
Вы можете отобразить имя файла, используя функцию write
с File
-объектом в качестве аргумента. Например, следующий оператор выводит имя файла:
x = new File("\path\file.txt");
write(x);
После создания File
-объекта Вы можете
использовать метод open
для открытия файла и чтения и записи. Метод open
имеет следующий синтаксис:
result = fileObjectName.open("mode");
Это метод возвращает true
, если операция прошла успешно, и false
в ином случае.
Если файл уже открыт, операция терпит неудачу, и оригинальный файл остаётся открытым.
Параметр mode
это строка, специфицирующая режим открытия файла. В
таблице описаны эти режимы.
Когда приложение заканчивает использование файла, оно
может закрыть его, вызвав метод close
. Если файл не открыт, close
терпит неудачу. Это метод возвращает true
при успехе и false
- в противном случае.
Часто доступ ко многим приложениям могут выполнять одновременно многие пользователи. Вообще разные пользователи не должны пытаться одновременно вносить изменения в файлы, поскольку это может привести к непредсказуемым ошибкам.
Чтобы предотвратить модификацию файла одновременно
несколькими пользователями, используйте один из механизмов блокирования,
предоставляемых службой Session Management Service, как описано в разделе
"Безопасное Совместное Использование Объектов с
Помощью Блокировки". Если один пользователь блокировал файл,
другие пользователи приложения должны ждать, пока файл не будет разблокирован. В
общем это означает, что lock
(замок/блокировка) должна предшествовать всем
файловым операциям; после выполнения операций должно выполняться unlock
(разблокирование).
Если только одно приложение может модифицировать данный
файл, Вы можете получать блокировку в объекте project
. Если более
чем одно приложение может иметь доступ к одному и тому же файлу, получайте
блокировку в объекте server
.
Например, у Вас создан файл myFile
. Затем Вы может использовать его так:
if ( project.lock() ) {
myFile.open("r");
// ... файл используется ...
myFile.close();
project.unlock();
}
Таким образом, только один пользователь приложения может изменять файл в данный
момент времени. Для более тонкого управления блокировкой Вы можете создать Ваш
собственный экземпляр класса Lock
для управления доступом к данному
файлу. Это описано в разделе "Использование Lock-Экземпляров".
Класс File
имеет несколько методов, которые можно использовать
после открытия файла:
setPosition
,
getPosition
, eof
. Это методы для установки и получения
текущей позиции указателя в файле и для определения, не находится ли указатель
в конце файла.read
, readln
, readByte
.write
, writeln
,
writeByte
, flush
.byteToString
,
stringToByte
. Конвертируют одно число в символ и наоборот.getLength
, exists
,
error
, clearError
. Для получения информации о файле и
для получения и очистки error-статуса.Эти методы описаны в последующих разделах.
Физический файл, ассоциированный с File
-объектом, имеет указатель
текущей позиции в файле. Когда Вы открываете файл, указатель находится в начале
либо в конце файла, в зависимости от режима, использованного при открытии файла.
В пустом файле начало и конец файла это одна точка.
Метод setPosition
позиционирует указатель в файле,
возвращая true
при успехе и false
- в ином случае.
fileObj.setPosition(position);
fileObj.setPosition(position, reference);
Здесь fileObj
это File
-объект, position
это целое число, указывающее позицию указателя, а reference
указывает относительную точку для position
таким образом:
Метод getPosition
возвращает текущую позицию в файле, где первый
байт файла это всегда байт 0. Этот метод возвращает -1, если имеется ошибка.
fileObj.getPosition();
Метод eof
возвращает true
, если указатель находится в
конце файла, и
false
- в ином случае. Этот метод возвращает true
после первой операции чтения, которая пытается прочесть после конца файла.
fileObj.eof();
Используйте методы read
, readln
и readByte
для чтения из файла.
Метод read
читает специфицированное
количество байтов из файла и возвращает строку.
fileObj.read(count);
Здесь fileObj
это File
-объект, а count
это целое число, специфицирующее количество байтов для чтения. Если count
специфицирует больше байтов, чем осталось в файле,
метод читает до конца файла.
Метод readln
читает следующую строку файла и возвращает её как строку.
fileObj.readln();
Здесь fileObj
это File
-объект. Символы-разделители строк
(\r\n
в Windows или просто \n
в Unix или Macintosh) не
включаются в строку. Символ \r
пропускается; \n
определяет действительный конец строки.
Этот компромисс даёт осмысленное поведение на всех платформах.
Метод readByte
читает следующий байт из файла и возвращает числовое значение следующего байта или -1.
fileObj.readByte();
Для записи в файл имеются методы write
, writeln
,
writeByte
и flush
.
Метод write
записывает строку в файл. В случае успеха операции
возвращает true
и false
- в ином случае.
fileObj.write(string);
Здесь fileObj
это File
-объект, в string
это строка JavaScript.
Метод writeln
записывает сроку в файл и
вводит последующие \n
(\r\n
в текстовом режиме Windows).
Возвращает true
при успешном выполнении записи и false
- в ином случае.
fileObj.writeln(string);
Метод writeByte
записывает байт в файл. Возвращает true
в случае успеха и false
- в противном случае.
fileObj.writeByte(number);
Здесь fileObj
это File
-объект, а number
это число.
Когда Вы используете один из этих методов, содержимое
файла внутренне буферизуется.
Метод flush
записывает буфер в файл на диске. Этот метод возвращает true
в случае успеха и false
- в противном случае.
fileObj.flush();
Есть два основных формата файлов : ASCII-текст и
бинарный.
Методы byteToString
и stringToByte
класса File
конвертируют данные этих форматов.
Метод byteToString
конвертирует число в односимвольную строку. Это
static-метод. Вы можете использовать класс File
сам по себе, а не
его экземпляр, для вызова этого метода.
File.byteToString(number);
Если аргумент - не число, метод возвращает пустую строку.
Метод stringToByte
конвертирует первый символ своего аргумента,
строку, в число. Это также static-метод.
File.stringToByte(string);
Метод возвращает числовое значение первого символа или 0.
Вы можете использовать несколько методов класса File
для получения
информации о файлах и работы с error-статусом.
Метод getLength
возвращает число символов в
текстовом файле или количество байтов в любом другом файле. Возвращает -1, если
возникла ошибка.
fileObj.getLength();
Метод exists
возвращает true
, если файл существует, и false
- в ином случае.
fileObj.exists();
Метод error
возвращает статус ошибки или -1, если файл не открыт
или не может быть открыт. Статус ошибки/error status это ненулевое значение,
если ошибка возникла, и 0 в ином случае (нет ошибки). Коды статуса ошибки
зависят от платформы; обратитесь к документации по Вашей ОС.
fileObj.error();
Метод clearError
очищает error-статус (значение error
)
и значение eof
.
fileObj.clearError();
На сервере Netscape имеется приложение-образец Viewer. Поскольку это приложение даёт возможность просматривать файлы на сервере, оно не устанавливается автоматически.
Viewer это хороший пример использования класса File
.
Если Вы установили это приложение, позаботьтесь об ограничении доступа к нему,
чтобы неавторизованный пользователь не мог просматривать файлы на сервере.
Об ограничении доступа к приложению см. раздел "Публикация
Приложения".
Следующий код из приложения Viewer создаёт экземпляр класса File
,
открывает его для чтения и генерирует HTML, отражающий строки файла, с
разделительной линией после каждой строки.
x = new File("\tmp\names.txt");
fileIsOpen = x.open("r");
if (fileIsOpen) {
write("file name: " + x + "<BR>");
while (!x.eof()) {
line = x.readln();
if (!x.eof())
write(line+"<br>");
}
if (x.error() != 0)
write("error
reading file" + "<BR>");
x.close();
}
Для взаимодействия с внешними приложениями рекомендуется использовать LiveConnect, как описано в Главе 14, "LiveConnect. Обзор.". Однако Вы можете также вызывать функции, написанные на других языках, таких как C, C++ или Pascal, и скомпилированных в библиотеки. Такие функции называются native-функции или внешние функции. Библиотеки внешних функций, называемые внешними библиотеками, являются библиотеками динамической компоновки/dll в ОС Windows и совместно используемыми объектами/shared objects - в ОС Unix.
Будьте осторожны при использовании внешних функций в Вашем приложении. Внешние функции могут нарушить защиту/безопасность, если внешняя программа выполняет команды пользователя в командной строке (например, программа, дающая возможность войти в ОС, или команды оболочки/shell). Эта функциональность опасна, так как хакер может присоединить дополнительные команды, используя точку с запятой для присоединения нескольких операторов. Лучше исключить использование ввода командной строки, если Вы не проверяете его достаточно жёстко.
Внешние функции используются в следующих случаях:
В директории примеров jsaccall
есть
несколько исходных и header-файлов, иллюстрирующих вызов функций внешних библиотек из приложения JavaScript.
В Application Manager Вы ассоциируете внешнюю библиотеку с определённым приложением. Но после того как библиотека ассоциирована с одним из приложений, она становится доступной всем другим установленным приложениям.
Выполните следующие действия для использования библиотеки внешних функций в приложении JavaScript:
registerCFunction
- для идентифицирования вызываемых функций
библиотеки - и callC
- для вызова этих функций. (См. "Регистрация
Внешних Функций" и
"Использование Внешних Функций в JavaScript")Важно!Вы обязаны рестартовать Ваш сервер, чтобы установить библиотеку для использования с приложениями. Вы обязаны рестартовать сервер каждый раз после добавления файлов новых библиотек или изменения имён файлов библиотек, используемых приложениями.
Хотя Вы можете написать внешние библиотеки на любом языке, JavaScript использует
соглашения языка C по вызову. Ваш код обязан подключать header-файл jsaccall.h
,
находящийся в директории js\samples\jsaccall\
.
Эта директория также содержит исходный код примеров
приложений, которые вызывают функции C, определённые в jsaccall.c
.
Просмотрите эти файлы, чтобы найти более конкретные рекомендации по написанию
функций C для использования с JavaScript.
Функции, вызываемые из JavaScript, обязаны быть экспортируемыми и обязаны соответствовать этому определению типа:
typedef void (*LivewireUserCFunction)
(int argc, struct
LivewireCCallData argv[],
struct LivewireCCallData* result, pblock* pb,
Session* sn, Request* rq);
Прежде чем Вы сможете запустить приложение, использующее функции внешних библиотек, Вы обязаны идентифицировать файлы этих библиотек. Используя Application Manager, Вы можете идентифицировать библиотеки, когда Вы устанавливаете приложение (щёлкнув Add) или когда модифицируете параметры инсталяции приложения (щёлкнув Modify). Дополнительно об идентификации файлов библиотек с помощью Application Manager см. "Установка Нового Приложения".
После ввода пути к файлам библиотек в Application Manager Вы обязаны рестартовать сервер, чтобы изменения вступили в силу. Затем необходимо скомпилировать и рестартовать приложение.
После идентификации внешних библиотек с помощью Application Manager
все приложения, запущенные на данном сервере, могут вызывать функции этих
библиотек (используя
registerCFunction
и callC
).
Используйте JavaScript-функцию registerCFunction
для регистрации
внешней функции для использования с приложением JavaScript. Эта функция имеет
следующий синтаксис:
registerCFunction(JSFunctionName, libraryPath, CFunctionName);
Здесь JSFunctionName
это имя функции как она
будет вызываться в JavaScript функцией callC
. Параметр libraryPath
это полный путь к библиотеке, использующий соглашения Вашей ОС, а параметр
CFunctionName
это имя C-функции как она определена в библиотеке.
В вызове этого метода Вы обязаны вводить имя точно в указанном регистре,
указанном в Application Manager, даже в ОС NT.
ПРИМЕЧАНИЕ:
Backslash (\) это специальный символ в JavaScript, поэтому Вы обязаны использовать forward slash (/) или двойной backslash (\\) для отделения Windows-директории и имён файлов в
libraryPath
.
Данная функция возвращает true
, если функция зарегистрирована успешно, и
false
- в ином случае. Функция может потерпеть неудачу, если JavaScript
не сможет найти библиотеку по специфицированному пути или не найдёт
специфицированную функцию в библиотеке.
Приложение обязано использовать registerCFunction
для регистрации
функции, прежде чем сможет использовать
callC
для её вызова. После того как приложение зарегистрировало
функцию, оно может вызывать эту функцию любое число раз. Хорошим местом для
регистрации функций является начальная страница приложения.
После того как Ваше приложение зарегистрировало функцию, оно может использовать callC
для её вызова. Эта функция имеет следующий синтаксис:
callC(JSFunctionName, arguments);
Здесь JSFunctionName
это имя функции, как она была идентифицирована
с помощью
registerCFunction
, а arguments
это список разделённых
запятыми аргументов внешней функции. В качестве аргументов могут использоваться
любые значения JavaScript: строки, числа, булевы значения,
объекты или null. Количество аргументов обязано соответствовать количеству
необходимых аргументов внешней функции. Хотя Вы можете специфицировать объект JavaScript
в качестве аргумента, это используется редко,
поскольку объект конвертируется в строку перед передачей внешней функции.
Эта функция возвращает строковое значение, возвращённое внешней функцией.
Функция callC
может возвращать только строковые значения.
Приложение-образец jsaccall
иллюстрирует использование внешних
функций.
Директория jsaccall
содержит исходный код C (в jsaccall.c
),
определяющий C-функцию с именем mystuff_EchoCCallArguments
. Эта
функция принимает любое количество аргументов и возвращает строку, содержащую HTML
с перечислением аргументов. Это пример иллюстрирует вызов функций
C из приложения JavaScript и возвращаемые значения.
Чтобы запустить jsaccall
, Вы обязаны скомпилировать jsaccall.c
имеющимся у Вас компилятором C. Командные строки для нескольких распространённых
компиляторов даны в файле в виде комментариев.
Следующие операторы JavaScript (взятые из jsaccall.html
)
регистрируют C-функцию как
echoCCallArguments
в JavaScript, вызывают функцию echoCCallArguments
,
а затем генерируют HTML на основе значения, возвращённого данной функцией.
var isRegistered = registerCFunction("echoCCallArguments",
"c:\\mycode\\mystuff.dll", "mystuff_EchoCCallArguments");
if (isRegistered == true) {
var returnValue = callC("echoCCallArguments",
"first arg",
42,
true,
"last arg");
write(returnValue);
}
else {
write("registerCFunction() returned
false, "
+ "check server error log for details")
}
Функция echoCCallArguments
создаёт
результирующую строку, содержащую HTML, который выводит тип и значение каждого
переданного ей аргумента JavaScript. Если
registerCFunction
возвращает true, вышеприведённый код генерирует
такой HTML:
argc = 4<BR>
argv[0].tag: string; value = first arg<BR>
argv[1].tag: double; value = 42<BR>
argv[2].tag: boolean; value = true<BR>
argv[3].tag: string; value = last arg<BR>
Обычный запрос, высылаемый клиентом на сервер, не имеет content type
(тип содержимого). Машина выполнения JavaScript автоматически обрабатывает такие запросы.
Однако, если пользователь отправляет форму, то клиент автоматически помещает content type
в шапку/header, чтобы сообщить серверу, как интерпретировать данные формы. Этот content type обычно
application/x-www-form-urlencoded
. Машина выполнения также
автоматически обрабатывает запросы с этим content type. В таких ситуациях Вам
редко нужен прямой доступ к шапкам/header запроса или ответа. Если, однако, Ваше
приложение использует иной content type, оно обязано уметь работать с шапкой запроса.
В свою очередь, типичный ответ сервера клиентку имеет тип содержимого text/html
.
Машина выполнения автоматически добавляет этот content type в свой ответ. Если
Вам в ответе нужен другой content type, Вы обязаны предоставить его сами.
Для поддержки этих потребностей машина выполнения JavaScript на сервере даёт
возможность Вашему приложению иметь доступ к
(1) шапке/header любого запроса и к (2) телу запроса, имеющего нестандартный content type.
Вы уже контролируете тело ответа тэгом SERVER
и тэгами HTML.
Функциональность, описанная в этом разделе, даёт также возможность управлять шапкой/header ответа.
Вы можете использовать эту функциональность в различных целях. Например, как описано в разделе "Использование Кук", можно осуществлять связь серверных и клиентских процессов с помощью кук. Также Вы можете использовать эту функциональность для поддержки выгрузки файлов.
World Wide Web Consortium публикует онлайновую информацию о протоколе HTTP и о том, что может пересылаться по этому протоколу. См., например, HTTP Specifications and Drafts .
Для доступа к парам имя/значение шапки клиентского запроса используйте метод httpHeader
объекта request
. Этот метод возвращает объект, чьи свойства и
значения соответствуют парам имя/значение шапки.
Например, если запрос содержит куки, header["cookie"]
или
header.cookie
будет его значением. Свойство cookie
,
содержащее все пары имя/значение этой куки (со значениями, кодированными так,
как описано в разделе "Использование Кук"),
обязано разбираться Вашим приложением.
Следующий код выводит свойства и значения шапки:
var header = request.httpHeader();
var count = 0;
var i;
for (i in header ) {
write(count + ". " + i + " " + header[i] + "<br>\n");
count++;
}
Если Вы отправили форму методом GET
, на
выходе получится примерно так:
0. connection Keep-Alive
1. user-agent Mozilla/4.0b1 (WinNT; I)
2. host piccolo:2020
3. accept image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
Если для отправки формы использован метод POST
,
вывод будет таким:
0. referer http://piccolo:2020/world/hello.html
1. connection Keep-Alive
2. user-agent Mozilla/4.0b1 (WinNT; I)
3. host piccolo:2020
4. accept image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
5. cookie NETSCAPE_LIVEWIRE.oldname=undefined; NETSCAPE_LIVEWIRE.number=0
6. content-type multipart/form-data; boundary=---------------------------79741602416605
7. content-length 208
Для нормальных HTML-запросов content type (тип содержимого) запроса будет application/x-www-form-urlencoded
.
После получения запроса с этим content type машина выполнения JavaScript на
сервере обрабатывает запрос, используя данные из тела запроса. В этой ситуации
Вы не можете получить прямой доступ к необработанным данным тела запроса. (Конечно,
Вы можете получить доступ к его содержимому через объекты
request
и client
, сконструированные машиной
выполнения).
Если, однако, запрос имеет любой иной content type, машина выполнения не обрабатывает автоматически тело запроса. В этом случае Ваше приложение должно определить, что делать с содержимым.
Возможно, другая страница Вашего приложения отправила запрос этой странице. Следовательно, Ваше приложение обязано предусматривать возможность получения необычного content type и должно знать, как его обработать.
Для получения доступа к телу запроса Вы используете
метод getPostData
объекта request
. Этот метод
принимает в качестве параметра количество символов тела. Если Вы специфицируете 0,
тело возвращается целиком. return-значение это строка, содержащая запрошенные
символы. Если доступных данных нет, метод возвращает пустую строку.
Можно использовать этот метод для получения всех символов за один раз или читать участки данных. Представляйте тело запроса как поток символов. При чтении Вы можете только продвигаться вперёд; Вы не можете читать одни и те же символы несколько раз.
Чтобы назначить всё тело запроса переменной postData
, можно
использовать следующий оператор:
postData = request.getPostData(0);
Если в качестве параметра специфицировано 0, метод
получает весь запрос. Вы можете точно определить, сколько символов содержится в
информации, используя свойство content-length
шапки таким образом:
length = parseInt(header["content-length"], 10);
Для получения тела запроса небольшими блоками Вы можете специфицировать иной параметр. Например, следующий код обрабатывает тело запроса блоками по 20 символов:
var length = parseInt(header["content-length"], 10);
var i = 0;
while (i < length) {
postData = request.getPostData(20);
// ...обработка postData...
i = i + 20;
}
Конечно, такой подход имеет смысл только тогда, когда Вы знаете, что блоки состоят из 20 символов информации.
Если отправляемый клиенту ответ/response использует специальный content type
(тип содержимого), Вы должны кодировать этот content type в шапке ответа. Машина
выполнения JavaScript автоматически добавляет content type по умолчанию
(text/html
) в шапку ответа/response header. Если вам необходима
специальная шапка, Вы обязаны сначала удалить из шапки старый content type по
умолчанию, а затем уже добавить новый. Это делается при помощи функций
addResponseHeader
и deleteResponseHeader
.
Например, если Ваш response использует royalairways-format
как специальный
content type, Вы можете специфицировать его так:
deleteResponseHeader("content-type");
addResponseHeader("content-type","royalairways-format");
Вы можете использовать функцию addResponseHeader
для добавления в
шапку ответа любой другой нужной информации.
Помните, что header отсылается с первой частью ответа/response. Следовательно, Вы должны вызывать эти функции раньше в скрипте на каждой странице. В общем, Вы должны быть уверены, что header ответа установлен до любого из следующих событий:
flush
для очистки буфера вывода.redirect
для изменения клиентских запросов.Дополнительно см. разделы "Очистка Буфера Вывода" и "Процессинг Времени Выполнения на Сервере".
1 http://info.internet.isi.edu:80/in-notes/rfc/files/rfc1341.txt
Дата последнего обновления: 29 сентября 1999 г.
© Copyright ╘ 1999 Sun Microsystems, Inc. Некоторая часть Copyright ╘ 1999 Netscape Communications Corp. Все Права Зарезервированы.