В этом разделе вы продолжите изучение свойств и методов объекта http (их достаточно много см. описание объекта http).
В зависимости от параметров URL запроса (путь, аргументы, текущее состояние сервера) вы можете сформировать ответ серверу различными способами. Первый способ, основанный на функции http.respPlainText() вы уже рассмотрели, в этом случае сервер отдает даже не HTML страницу, а обычный текст. Но для сервера, деятельность которого очень сильна связана с формированием и поддержкой динамических страниц, - этот метод наиболее часто встречается. Действительно, для управления, снятия и отображения показаний различных приборов требуются именно динамические страницы, а они в свою очередь связаны с Ajax запросами, которые всегда есть текст, возможно различного формата, но текст. Но это вас ждет впереди, а сейчас рассмотрите вариант выдачи именно HTML страницы.
HTML это тоже чистый текст, но хорошо сдобренный всяческими тегами. Создайте файл командного скрипта cmdHtml.js (впрочем он уже есть в папке stuff@examples/helloWorld/) и установите его в jcjs.xml, так как указано в предыдущем разделе. Перезапустим сервер.
var str = '<html>' +
'<head>' +
'<title>Заголовок страницы</title>' +
'</head>' +
'<body>' +
'<h1><b>Hello World!</b></h1>' +
'</body>' +
'</html>';
http.setBody(str);
http.respContentType('text/html');
В браузере вы увидите слова Hello World! Но уже написанные большими жирными буквами, - работает HTML разметка, так как в respContentType указан тип данных 'text/html'. Особенностью данного типа формирования ответа является является вызов двух функций объекта http: сначала вы устанавливаем тело ответа в виде строки http.setBody(str), а потом делаем ответ, указывая тип содержимого http.respContentType('text/html').
Врочем, для каких-либо специальных случаев заголовок HTTP ответа можно также сформировать вручную, изменив последние строки так:
...
http.setBody(str); // или http.bodyStr = str;
var header = '';
header += 'HTTP/1.1 200 OK\r\n';
header += 'Content-Length: ' + http.bodySize + '\r\n';
header += 'Content-Type: text/html; charset=utf-8\r\n';
header += 'Connection: keep-alive\r\n'
header += '\r\n';
http.respFull(header + str);
// если отправили в http.respFull() то http.respContentType() уже не нужен
//http.respContentType('text/html');
Здесь вы можете увидеть использование еще одного свойства объекта http.bodySize - оно указывает размер тела ответа в байтах, установленного ранее функцией http.setBody(). Проверяем работу нового командного скрипта без перезагрузки сервера. Должно все остаться на месте.
Применяемая функция http.respFull() - совсем универсальная функция, которая позволяет сформировать HTTP ответ "вручную", в виде одного заголовка ответа и тела ответа одновременно. Основное назначение http.respFull(), конечно, не для формирования текстовых ответов, а в возможности передать полномочия формирования ответа какому-либо объекту, например, плагину PHP, но об этом не сейчас.
Формировать ответ в виде HTML страницы способом, как в Листинг 1 не самая лучшая затея, можно совершить ошибки в расстановке тегов, кавычек и т.д. Напрашивается вопрос: "ну неужели нельзя отдать клиенту страницу из готового файла?" Можно. Функция http.respFile() способна прочитать файл и отдать ее клиенту, автоматически сформировав заголовок по суффиксу файла. Вот пример, который отдает эту страницу документации:
http.respFile('stat@docs/p4_object_http.html');
Или вот ответ в виде картинки: http.respFile('stat@favicon.png'). Теперь, наверное, у вас сложился примерный план действий как "зарядить" jCjS на некоторую иерархию сайта для обслуживания какого-либо прибора(ов). Пишем командный скрипт так, чтобы с главной страницы / уходила основная страница на которой есть всякие ссылки на другие подразделы, которые могут иметь "файловую природу" а некоторые и природу "синтеза контента на лету" с использованием JavaScript. Это все вас ждет впереди, а сейчас необходимо представить еще одну функцию http.respTmplFile().
Функция http.respTmplFile() работает аналогично http.respFile() за исключением того, что она предназначена выдачи только текстовых данных(страниц) с проведенной шаблонной обработкой. По замыслу этот прием аналогичен вставкам PHP, а по реализации отличие заключается в том, что содержание вставок пишется на JavaScript. Вот пример командного скрипта выдачи шаблонной обработки:
http.respTmplFile('stuff@examples/helloWorld/tmp.html');
//или
http.respTmplFile('stuff@examples/helloWorld/js/script.js', "text/javascript");
//или
http.respTmplFile('stuff@examples/helloWorld/css/style.css');
http.respTmplFile('stuff@examples/helloWorld/css/style.css', "text/css");
Второй аргумент функции http.respTmplFile() не обязятельный. Строки 5 и 6 выдают идентичный результат работы, т.к. генерация HTTP заголовка ContentType происходит по формуле ContentType = text/fileSuffix
А вот пример шаблонной страницы, вставки JavaScript, которые должны быть выполнены
функцией http.respTmplFile(), как говорится на стороне сервера вводятся такими специальными
комментариями
Содержимое вставки заполняется результатом последнего операнда скрипта:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta content="charset=utf-8">
<title>Пример шаблонной обработки</title>
</head>
<body>
<h2>Пример шаблонной обработки</h2>
как известно 2*2=<!--= 2*2 -->, а тем временем... <br>
<br>
Время на сервере:
<!--=
var time = new Date();
time.getHours() + ':' +
time.getMinutes() + ':' +
time.getSeconds();
--><br>
Время на этой машине:
<script>
var time = new Date();
document.write(
time.getHours() + ':' +
time.getMinutes() + ':' +
time.getSeconds()
);
</script>
</body>
</html>
Если обработка не будет произведена, например, файл HTML страница открылась браузером локально, то они будут восприняты как обычные комментарии. Тем самым, прием HTTP вставок будет полезен для отличения открыта страница локально или загружена с сервера. Так вот если с сервера, то JavaScript-ом на стороне браузера можно вставить поле движка поиска какого-либо контента, а если локально, то поиска нет. Далее мы будем часто решать различные проблемы вставками JavaScript кода очень просто и элегантно.
относятся: ответ в виде номера ошибки HTTP http.respError(numError, addDesc), addDesc - аргумент в котором вы можете сообщить дополнительную информацию, например, причину ошибки.
Ответ в виде редиректа на другую страницу http.respRedirect(url). Полезная функция для перенаправления на главную страницу (например, при получении куки, об этом позднее). Имейте в виду, что перенаправление на другой сайт необходимо писать с указанием полного URL http.respRedirect('http://google.ru'). Для локального редиректа можно URL не указвать http.respRedirect('/docs/').
Ну и в заключение, есть функция закрытия соединения http.respCloseConnection(). Она может понадобиться для отсечки нежелательных адресов, пользователей и так далее.
Сейчас мы доделаем Листинг 6 до сколько-нибудь полезной вещи, а именно до страницы на которой обновляется время на локальной машине и на сервере раз в секунду. Будут задействованы два файла: cmdDiffTime.js и tmpDiffTime.html из папки stuff@examples/helloWorld/;
(function() {
if(http.argCnt == 0 && http.pathCnt == 0) {
http.respFile('tmpDiffTime.html');
return;
}
if(http.argExist('time')) {
var time = new Date();
var h = time.getHours(); if(h < 10) { h = '0' + h; }
var m = time.getMinutes(); if(m < 10) { m = '0' + m; }
var s = time.getSeconds(); if(s < 10) { s = '0' + s; }
http.respPlainText(h + ':' + m + ':' + s);
return;
}
http.respError(404);
return;
})();
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script language="javascript" type="text/javascript" src="/jsl/jquery.min.js"></script>
<script language="javascript" type="text/javascript">
var timeSend;
function requestTime() {
timeSend = new Date().getTime();
$.get("?time", ansTime).error(ansError);
}
function ansTime(ans) {
$('#st').html(ans + ' (delay = ' + (new Date().getTime() - timeSend) + 'мс)');
fillLocalTime();
setTimeout(requestTime, 1000);
}
function ansError(ans) {
$('#st').html('?');
fillLocalTime();
setTimeout(requestTime, 1000);
}
function fillLocalTime() {
var time = new Date();
var h = time.getHours(); if(h < 10) { h = '0' + h; }
var m = time.getMinutes(); if(m < 10) { m = '0' + m; }
var s = time.getSeconds(); if(s < 10) { s = '0' + s; }
$('#lt').html(h + ':' + m + ':' + s);
}
$(requestTime);
</script>
<title>Разница во времени</title>
</head>
<body>
<table>
<tr>
<td>Время на сервере jCjS:
<td><span id="st"></span>
</tr>
<tr>
<td>Время на этой машине:
<td><span id="lt"></span>
<tr>
<table>
</body>
</html>
Внимательно рассмотрите эти два файла, их понимание является тестом возможности дальнейшего чтения этой документации по jCjS. Касательно jCjS на данный момент все, что в них используется - описано. Но Вам могут быть не понятны фрагменты кода:
| tmpDiffTime.html | |
| Что такое <span id="st"></span> | Не плохо бы подучить язык разметки HTML |
| Непонятно все от <script language="javascript" type="text/javascript"> до </script> | Необходимо изучение языка JavaScript |
| Что значит $(requestTime); или $('#st').html('?'); | Необходимо изучение библиотеки jQuery |
| cmdDiffTime.js | Непонятно, что значит обертка кода (function() { ... } )(); | Необходимо изучение языка JavaScript |