Назначение

Чтобы понять сущность объекта http, проведем небольшой экскурс в ядро jCjS. Начнем с поверхностного ознакомления с протоколом HTTP. При вводе в адресную строку браузера строки вида
http://127.0.0.1:8080/postsTable/index.html?arg1=val1&arg2=val2
браузер формирует запрос header и отсылает его серверу. Header имеет вот такой вид

GET /postsTable/index.html?arg1=val1&arg2=val2 HTTP/1.1\r\n
Host: localhost:8080\r\n
Connection: keep-alive\r\n
Accept: text/html, application/xhtml+xml, */*\r\n
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko\r\n
Accept-Encoding: gzip,deflate,sdch\r\n
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4\r\n\r\n
// Делее могут следовать данные POST (это если браузер что нибудь отсылает серверу)

С помощью этого заголовка браузер не только передает информацию о запрашиваемом ресурсе, но и предосталяет серверу информацию о себе и своих возможностях.

jCjS выступая в роли HTTP сервера принимает этот запрос и создает объект jCjSHttpConnection. Затем производит поиск поста одноименного с каталогом (postsTable) в который обращается браузер, если такой пост найден, сервер jCjS создает в JS контексте найденного поста объект jCjSHttpConnection с глобальным именем http и выполняет скрипт cmd.js. Задача этого скрипта обработать запрос и сформировать ответ браузеру

Итак: назначение объекта http - формирование ответа браузеру в скрипте cmd.js


Свойства (property)

Пример использования:

//свойство параметра чтение/запись:
// Чтение
var prop = server.property;
// Запись
var prop = 'testString';
server.property = prop;

String http.objectName Только чтение
Возвращает имя объекта http (всегда "http" за исключением отложенных соединений. см. moveConnectionToDelay)

var httpName = http.objectName; // httpName == "http";


int http.id Только чтение
Возвращает уникальный идентификатор соединения

var id_http = http.id;


int http.isIE Только чтение
Возвращает версию Internet Explorer-a (0 - если не Internet Explorer)






int http.isFF Только чтение
Возвращает версию браузера Firefox (0 - если не Firefox)


int http.isChrome Только чтение
Возвращает версию браузера Google Chrome (0 - если не Chrome)


int http.isOpera Только чтение
Возвращает версию браузера Opera (0 - если не Opera)


int http.isEdge Только чтение
Возвращает версию браузера Edge Microsoft (0 - если не Edge)


bool http.isLocal Только чтение
Возвращает true если соединение открыто с локального хоста


int http.tag Чтение/запись
Свойство для сохранения некоторой информации в контексте JS
(как правило это необходимо в отложенных соединениях)
ВНИМАНИЕ!!! этот параметр задействован в include/language.js, будьте внимательны при его использовании

var tag = http.tag; // по умолчанию 0
http.tag = 50;


String http.contentName Чтение/запись
Наименование передаваемых данных
(для удобства сохранения пользователем полученных данных на диск)

var contentName  = http.contentName; // по умолчанию ''
http.contentName = 'warning_on.txt';

http.bodyStr = "?warning&on=" + http.argByKey("on") + " Ok";
http.respContentType('text/plain');
// Браузер получит страницу, и если пользователь вздумает сохранит ее на диск(Ctrl+S),
// ему будет предложено имя 'warning_on.txt'


bool http.saveToDisk Чтение/запись
Принудительно предложить пользоавателю сохранить данные на диск
(механизм работает только если установлен http.contentName)

Браузер получит страницу, и сразу предложит ее сохранить (или сразу ее сохранит) - зависит от настроек браузера

http.saveToDisk  = true;
http.contentName = 'warning_on.txt';

http.bodyStr = "?warning&on=" + http.argByKey("on") + " Ok";
http.respContentType('text/plain');
// Браузер получит страницу, и сразу предложит ее сохранить


String http.header Только чтение
Весь заголовок запроса браузера

var client_query = http.header;


int http.headerCnt Только чтение
получить количество заголовков (полей HTTP запроса)

var h_cnt = http.headerCnt;  // возвратит количество строк в header запроса


header http.method Только чтение
метод запроса GET или POST

switch(http.method)
{
case 'GET':
case 'POST':
    ...
break;
default:
    http.respError(500, 'Сервер обслуживает только GET и POST запросы');
break;
}


String http.headerFirstStr Только чтение
Первая строка из header

var firstStrQuery = http.headerFirstStr; // Получим  'GET /postsTable/index.html?arg1=val1&arg2=val2 HTTP/1.1'


String http.auth Только чтение
получить закодированную строку Basic авторизации ('' если авторизации пользователя еще небыло)

var auth = http.auth;                    // Получим  'QWRtaW46c3lzdGVt'
var decodeStr = server.fromBase64(auth); // Получим  'Admin:system'
var arr = decodeStr.split(':');
var user = arr[0];
var pass = arr[1];


String http.cookie Только чтение
Получить переданные клиентом куки

var client_cookie = http.cookie; // Получим  ''  TODO: add cookie


String http.httpVer Только чтение
Получить строку версии HTTP

var httpVer = http.httpVer; // Получим  'HTTP/1.1'


String http.pathUrl Только чтение
получить полный запрос Url (без аргументов, следующих после символа '?')

var pathUrl = http.pathUrl; // Получим  '/postsTable/index.html'


String http.path Только чтение
получить полный запрос Url (без каталога поста и без аргументов, следующих после символа '?')

var path = http.path; // Получим  '/index.html'


int http.pathCnt Только чтение
получить количество вложенностей путей запроса

var cnt = http.pathCnt;
// Получим  0 при запросе '/index.html'
// Получим  1 при запросе '/postsTable/index.html'
// Получим  3 при запросе '/postsTable/devs/dip/index.html'


String http.pathFirst Только чтение
получить первую часть пути от каталога поста ("" - если "/")

var firstPath = http.pathFirst;
// Получим  ''           при запросе '/postsTable/'
// Получим  'index.html' при запросе '/postsTable/index.html'
// Получим  'devs'       при запросе '/postsTable/devs/dip/index.html'


String http.pathLast Только чтение
получить последнюю часть пути ("" - если "/")

var lastPath = http.pathLast;
// Получим  ''           при запросе '/postsTable/'
// Получим  'index.html' при запросе '/postsTable/index.html'
// Получим  'index.html' при запросе '/postsTable/devs/dip/index.html'


String http.pathToUp Только чтение
получить последнюю часть пути от каталога поста

var path2Up = http.pathToUp;
// Получим  ''          при запросе '/postsTable/'
// Получим  '/'         при запросе '/postsTable/index.html'
// Получим  '/devs/dip' при запросе '/postsTable/devs/dip/index.html'


String http.peerAddress Только чтение
получить ip-адрес клиента

var ip = http.peerAddress;


String http.pathInfo Только чтение
Директория в которую был запрос

var pathInfo = http.pathInfo;
// Получим  '/postsTable/'          при запросе '/postsTable/'
// Получим  '/postsTable/'          при запросе '/postsTable/index.html'
// Получим  '/postsTable/devs/dip/' при запросе '/postsTable/devs/dip/index.html'


String http.file Только чтение
Получить имя запрашиваемого файла

var file = http.file;
// Получим  ''           при запросе '/postsTable/'
// Получим  ''           при запросе '/postsTable/devs'
// Получим  'index.html' при запросе '/postsTable/index.html'
// Получим  'index.html' при запросе '/postsTable/devs/dip/index.html'
// Получим  ''           при запросе '/postsTable/devs/dip/indexhtml'


String http.fileSuff Только чтение
Получить расширение файла

var suff = http.fileSuff;
// Получим  ''     при запросе '/postsTable/'
// Получим  ''     при запросе '/postsTable/devs'
// Получим  'html' при запросе '/postsTable/index.html'
// Получим  'txt'  при запросе '/postsTable/devs/dip/file.txt'


int http.argCnt Только чтение
получить количество аргументов

var arg_cnt = http.argCnt;
// Получим  2 при запросе '/index.html?arg1=val1&arg2=val2'
// Получим  0 при запросе '/postsTable/index.html'
// Получим  4 при запросе '/postsTable/devs/dip/index.html?arg1=val1&arg2=val2&arg3&arg4'


int http.postBodyLen Только чтение
Запрос POST: длина загружаемого тела POST запроса


String http.postType Только чтение
Запрос POST: получить текст перечесленного типа данных


int http.postFragsCnt Только чтение
Запрос POST multipart/form-data: количество фрагментов запроса


String http.cookieForSend Чтение/запись
в ответе установить куки


String http.bodyStr Только запись
установить тело ответа в виде строки
Для чтения используйте http.getBodyStr()

http.bodyStr = '<html>' +
               '<head>' +
               '<title>Заголовок страницы</title>' +
               '</head>' +
               '<body>' +
               '<h1>Заголовок</h1>' +
               '</body>' +
               '</html>';
http.respContentType('text/html');


String http.bodyArr Только запись
установить тело ответа (автоматически распознает тип данных)
Для чтения используйте http.getBodyArr()

http.bodyArr = '<html>' +
               '<head>' +
               '<title>Заголовок страницы</title>' +
               '</head>' +
               '<body>' +
               '<h1>Заголовок</h1>' +
               '</body>' +
               '</html>';
http.respContentType('text/html');


int http.bodySize Только чтение
текущий размер данных ответа

http.bodyStr = "Ok";
var size = http.bodySize; // Возвратит 2


String http.host Только чтение
Имя запрошенного хоста.
jCjS можно настроить в качестве хостинга и при разных именах хостов в запросе выдавать разные страницы.
Чтобы воспользоваться этой технологией, необходимо зарегистрировать доменное имя(Alias или CName) на сервере DNS. и указать ip установленного jCjS

switch(http.host){
case 'post1.jcjs.ru':
case 'post2.jcjs.ru': http.respPlainText("Вы обратились к хосту " + http.host); break;
default:              http.respPlainText("Вы обратились к дефолтному хосту");   break;
}


String http.url Только чтение
URL запрошенной страницы (вместе с аргументами GET).


bool http.isReady Только чтение
Готов к использованию функций http.resp*()


bool http.isFinished Только чтение
Ответ на запрос уже был, функции http.resp*() использовать нет смысла


bool http.isEncrypted Только чтение
Текущее соединение использует https

// пример редиректа с http на https
if(server.https && !http.isLocal && !http.isEncrypted) {
  if(typeof QUrl === 'undefined') post.install('QUrl')
  var url  = new QUrl(http.url)
                     .setScheme('https')
                     .setPort(server.https_port)
  return http.respRedirect(url.url)
}

String http.sslProto Только чтение
Выводит тип шифрования если соединение использует https
Вывод примерно такой: TLSv1_2, SSLv3, ...


Сигналы

void http.closed() Сигнал

генерируется объектом http при разрыве соединения с клиентом

// в cmd.js
asidk.add_dconn(10000);

// в init.js сформировать функции
ASIDK.prototype.add_dconn             = function add_dconn(tout){

    if(typeof http !== "object" || String(http).indexOf('Http') < 4)
        return post.throwScript('не найден http объект');

    if(typeof tout !== "number")
        return post.throwScript('tout не является числом');

    var dconn = post.moveConnectionToDelay(), self = this;
    dconn.rem_dconn = function rem_dconn(){
        //post.log('-' + http.id + ' rem');
        delete self.http_events[this.id]; // удалить из списка отложеных
        this.closed.disconnect(this, this.rem_dconn);
        post.removeDelayConnection(this);
    };
    // подсоединиься к сигналу closed
    dconn.closed.connect(dconn, dconn.rem_dconn);

    dconn.send_event = function send_event(obj) { // Создать функцию обработчик события
        obj = obj ? obj : {evnt:'tout'};
        obj.dt = new Date().valueOf();
        try{
            this.setBody( JSON.stringify(obj) );
            this.respContentType("text/json");
            this.rem_dconn.call(this);
        }catch(e){
            post.log("e", e.fileName + ':' + e.lineNumber + ' "' + e.message + '"');
        };
    };
    this.http_events[dconn.id] = dconn; // сохранить в списке отложеный
    this.send_event();
}

// теперь по таймеру timer_events опрашивать готовность отправки
// или сразу всем принудительно, указав в аргументе объект
ASIDK.prototype.send_event            = function send_event(evnt){
    /* отправка событий на отложенные соединения*/
    var send = (typeof evnt === "object"),
          dt = new Date().valueOf();

    var count = 0;
    for(var k in this.http_events)
    {
        count++;
        var http = this.http_events[k];
        if(send || http.dt < dt) {
            //post.log('-' + http.id + ' rem');
            http.send_event.apply(http, [evnt]);
            delete this.http_events[k];
        }
    }

    this.timer_events.stop();
    if(!count)    return;
    this.timer_events.start(this.timer_events.interval);
    //post.log(new Date().valueOf() + ': count=' +count);
}

function ASIDK(){
    this.timer_events = new QTimer();
    this.timer_events.timeout.connect(this, this.send_event);
    this.timer_events.interval = 1000;
    this.timer_events.start(this.timer_events.interval);
}

asidk = new ASIDK();


Методы

String http.pathByNum(int num)
получить часть пути по номеру ("" - если его нет)

// запрос '/postsTable/devs/dip/index.html?arg1=val1&arg2=val2&arg3&arg4'
var dir = http.pathByNum(0); // возвратит 'postsTable'
var dir = http.pathByNum(1); // возвратит 'devs'
var dir = http.pathByNum(2); // возвратит 'dip'
var dir = http.pathByNum(3); // возвратит ''


String http.pathFromNum(int num)
получить путь начиная с номера ("" - если его нет)

// запрос '/postsTable/devs/dip/index.html?arg1=val1&arg2=val2&arg3&arg4'
var dir = http.pathFromNum(0); // возвратит '/postsTable/devs/dip/index.html'
var dir = http.pathFromNum(1); // возвратит '/devs/dip/index.html'
var dir = http.pathFromNum(2); // возвратит '/dip/index.html'
var dir = http.pathFromNum(3); // возвратит '/index.html'
var dir = http.pathFromNum(4); // возвратит ''


bool http.headerExist(key)
существует ли поле с ключом key

if(http.headerExist('Accept-Encoding'))
{
    var val = http.headerByKey('Accept-Encoding');
    if(val.indexOf('deflate') != -1)
    {
        // Браузер поддерживает распаковку данных zip
    }
}


String http.headerByKey(key)
получить поле по ключу ("" - если его нет)

var val = http.headerByKey('Accept-Encoding');
if(val.indexOf('deflate') != -1)
{
    // Браузер поддерживает распаковку данных zip
}


String http.headerKeyByNum(num)
получить ключ по номеру ("" - если его нет)

// Что прислал браузер (см. Листринг 1)

var val = http.headerByKey(4); // Вернет 'Accept-Encoding'


String http.headerByNum(num)
получить поле по номеру ("" - если его нет)

// Что прислал браузер (см. Листринг 1)

var val = http.headerByNum(4); // Вернет 'gzip,deflate,sdch'


bool http.argExist(key)
существует ли аргумент с ключом key

// запрос '/postsTable/devs/dip/index.html?arg1=val1&arg2=val2&arg3&arg4'
var exist
exist = http.argExist('arg4'); // Вернет true
exist = http.argExist('arg5'); // Вернет false


bool http.argEqual(key, val)
проверить наличие и равенство аргумента значению

// запрос '/postsTable/devs/dip/index.html?arg1=501&arg2=502'

var eq
eq = http.argEqual('arg1', '501'); // Вернет true
eq = http.argEqual('arg1', '502'); // Вернет false


String http.argByKey(key)
получить аргумент по ключу ("" - если его нет)

// запрос '/postsTable/devs/dip/index.html?arg1=val1&arg2=val2&arg3&arg4'
var val
val = http.argByKey('arg1'); // Вернет 'val1'
val = http.argByKey('arg4'); // Вернет ''
val = http.argByKey('arg5'); // Вернет ''


String http.argByKeyByteArr(key)
получить аргумент по ключу ("" - если его нет) в виде массива ByteArray


    if(http.argCnt > 1 && http.argKeyByNum(0) == 'sendPartFile')
    {
        ......

        switch(http.method)
        {
        case 'GET':
            // Запись сократилась до одной строки
            // http.argByKeyByteArr('data') - это объект ByteArray (данные защифрованы в Base64)
            // .fromBase64()                - расшифровка Base64 в массив ByteArray
            // .qobject                     - передать QObject (который владеет ByteArray) в функцию записи
            t.f.write( http.argByKeyByteArr('data').fromBase64().qobject );
            break;
        case 'POST':
            t.f.write( http.postBodyByteArr.fromBase64().qobject );
            break;
        }
        .....
    }


String http.argKeyByNum(num)
получить ключ по номеру ("" - если его нет)

// запрос '/postsTable/devs/dip/index.html?arg1=val1&arg2=val2&arg3&arg4'
var key
key = http.argKeyByNum(0); // Вернет 'arg1'
key = http.argKeyByNum(1); // Вернет 'arg2'
key = http.argKeyByNum(3); // Вернет 'arg4'
key = http.argKeyByNum(4); // Вернет ''


String http.getBodyStr()
получить тело отправляемых данных

http.bodyStr = 'тело документа';
console.log(http.bodyStr, http.getBodyStr());


ByteArray http.getBodyArr()
получить тело отправляемых данных

http.bodyArr = 'тело документа';
console.log(http.bodyArr, http.getBodyArr().toLocal8Bit());


String http.argByNum(num)
получить аргумент по номеру ("" - если его нет)

// запрос '/postsTable/devs/dip/index.html?arg1=val1&arg2=val2&arg3&arg4'
var val;
val = http.argByNum(0); // Вернет 'val1'
val = http.argByNum(1); // Вернет 'val2'
val = http.argByNum(3); // Вернет ''
val = http.argByNum(4); // Вернет ''


String http.argFirst()
Добавлено в r893: получить первый аргумент

// запрос '/postsTable/devs/dip/index.html?arg1=val1&arg2=val2&arg3&arg4'
var val = http.argFirst(); // Вернет 'val1'


String http.argLast()
Добавлено в r893: получить последний аргумент

// запрос '/postsTable/devs/dip/index.html?arg1=val1&arg2=val2&arg3&arg4=val4'
var val = http.argLast(); // Вернет 'val4'


String http.argKeyFirst()
Добавлено в r893: получить первый ключ

// запрос '/postsTable/devs/dip/index.html?arg1=val1&arg2=val2&arg3&arg4'
var val = http.argFirst(); // Вернет 'arg1'


String http.argKeyLast()
Добавлено в r893: получить последний ключ

// запрос '/postsTable/devs/dip/index.html?arg1=val1&arg2=val2&arg3&arg4'
var val = http.argKeyLast(); // Вернет 'arg4'


int http.postBodyToObj(Object)
Запрос POST: Передать данные пост-запроса объекту.
Аргументом могут выступать объекты ByteArray, jCjSFile, QIODevice
или любой другой объект Qt с методом data(QByteArray *)

Возвращает количество переданных байт данных объекту.
0 если POST данных не существует
-1 если объект не поддерживает прием данных

Будьте осторожны с массивными пост-запросами. Они копируются в оперативную память.

var f = new File();
var lenght = http.postBodyToObj(f);
// Данные POST запроса записаны в файл в размере lenght


String http.postBodyStr()
Запрос POST: забрать варианты получения целикового тела запроса в виде строки


String http.postBodyObj()
Запрос POST: забрать варианты получения целикового тела запроса в виде объекта, если прислан json


ByteArray http.postBodyByteArr()
Запрос POST: Возвращает тело запроса в виде массива ByteArray


    if(http.argCnt > 1 && http.argKeyByNum(0) == 'sendPartFile')
    {
        ......

        switch(http.method)
        {
        case 'POST':
            // Запись сократилась до одной строки
            // http.postBodyByteArr() - это объект ByteArray (данные защифрованы в Base64)
            // .fromBase64()          - расшифровка Base64 в массив ByteArray
            // .qarray                - передать QByteArray в функцию записи

            t.f.write( http.postBodyByteArr().fromBase64().qarray );
            break;
        case 'GET':
            t.f.write( http.argByKeyByteArr('data').fromBase64().qarray );
            break;
        }
        .....
    }


arr[Variant] http.postBodyArr()
Запрос POST: Возвращает тело запроса в виде JS массива


String http.postFragName(num)
Запрос POST multipart/form-data: получить значение атрибута name фрагмента


String http.postFragFileName(num)
Запрос POST multipart/form-data: получить значение атрибута filename фрагмента


String http.postFragContentType(num)
Запрос POST multipart/form-data: получить значение атрибута Content-Type фрагмента


int http.postFragSize(num)
Запрос POST multipart/form-data: получить размер блока


String http.postFragBodyStr(num)
Запрос POST multipart/form-data: получить тело фрагмента в виде строки


Object http.postFragBodyObj(num)
Запрос POST multipart/form-data: получить тело фрагмента в виде объекта, если прислан json


arr[Variant] http.postFragBodyArr(num)
Запрос POST multipart/form-data: получить тело фрагмента в виде массива


arr[Variant] http.postFragBodyByteArr(num)
Запрос POST multipart/form-data: получить тело фрагмента в виде массива ByteArray


int http.postFragBodyObj(num, Object)
Запрос POST multipart/form-data: Передать данные пост-запроса объекту.
Аргументом могут выступать объекты ByteArray, jCjSFile, QIODevice
или любой другой объект Qt с методом data(QByteArray *)

Возвращает количество переданных байт данных объекту.
0 если POST данных не существует
-1 если объект не поддерживает прием данных

Будьте осторожны с массивными пост-запросами. Они копируются в оперативную память.

var f = new File();
... // set fileName and open
var lenght = http.postFragBodyObj(f);
// Данные POST запроса записаны в файл в размере lenght
... // close file


void http.setBody(String)
установить тело ответа. Аргумент строка

var str = '';
str += '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">\r\n';
str += '<html>\r\n';
str += '<head>\r\n';
str += '<meta content="text/html; charset=utf-8">\r\n';
str += '<title>Hello World</title>\r\n';
str += '</head>\r\n';
str += '<body>\r\n';
str += '<h2>Hello World!</h2>\r\n';
str += '</body>\r\n';
str += '</html>\r\n';
http.setBody(str);
http.respContentType('text/html');


void http.setBody(Arr)
установить тело ответа. Аргумент массив


void http.setBody(Object)
установить тело ответа. Аргумент объект
Аргументом могут выступать объекты ByteArray, jCjSFile, QIODevice
или любой другой объект Qt с функцией data() возвращающем QByteArray *


void http.setHeader(String)
добавить в заголовок ответа пользовательские поля и отправить ответ. Аргумент строка
(тело сообщение уже должно быть установлено)
Поля Content-Length и Connection устанавливаются автоматически

var header = 'Content-Type: text/html; charset=utf-8\r\n';
http.setHeader(header);


void http.setHeader(Arr)
добавить в заголовок ответа пользовательские поля и отправить ответ. Аргумент массив байт
(тело сообщение уже должно быть установлено)
Поля Content-Length и Connection устанавливаются автоматически


void http.addExtHeader(String)
добавить к стандартным заголовокам ответа пользовательские поля


var cors = http.headerByKey('Origin')
if(cors != '')
{
    http.addExtHeader('Access-Control-Allow-Origin: ' + cors);
    http.addExtHeader('Access-Control-Allow-Credentials: true');
}

void http.respFull(Variant)
void http.respFull(Object)
передать полный ответ из Variant или объекта
это совсем универсальная функция, которая позволяет сформировать HTTP ответ "совсем вручную",
в виде одного заголовка ответа и тела ответа одновременно

// Установка тела сообщения
var body = ....
http.setBody(body)

// формирование заголовка
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 + body);


void http.respHeader(String header, bool dynamics = true, Date lastModif = new Date())
Установить заголовок и отправить ответ
(тело сообщения уже должно быть установлено) Аргументы:

  • header - поля заголовка
  • dynamics - управление кешем. Динамический/Статический контент (по умолчанию true)
  • lastModif - Время модификации (по умолчанию текущее)

  • void http.respError(int numError, String addDesc = "")
    ответ в виде ошибки

    http.respError(500);
    http.respError(500, 'Внутренняя ошибка');
    http.respError(404, 'Ресурс ' + http.pathUrl + ' не найден');
    


    void http.respRedirect(String)
    ответ в виде редиректа

    http.respRedirect('/'); // Перенаправить браузер в корень сайта
    
    http.respRedirect('/doc/index.html'); // Перенаправить браузер в документацию
    
    http.respRedirect('http://yandex.ru/'); // Перенаправить браузер на другой ресурс
    


    void http.dropAlive()
    void http.respCloseConnection() синонем
    void http.disconnectFromHost() синонем
    Разорвать соединение с клиентом

    http.respRedirect('http://yandex.ru/'); // Перенаправить браузер на другой ресурс
    http.dropAlive();
    // !!! Внимание, если вы перенаправляете на локальный скрипт .php
    //     то выполнение http.dropAlive();  будет излишним
    //     (Возможно и на любой относительный ресурс)
    


    void http.respContentType(String contentType, bool dynamics = true, Date lastModif = new Date())
    Установить заголовок и отправить ответ
    (тело сообщения уже должно быть установлено) Аргументы:

  • contentType - тип данных
  • dynamics - управление кешем. Динамический/Статический контент (по умолчанию true)
  • lastModif - Время модификации (по умолчанию текущее)
  • http.bodyStr = "?warning&on=" + http.argByKey("on") + " Ok";
    http.respContentType('text/plain', false, new Date());  // разрешить кеширование (по умолчанию 7 дней)
    // или
    http.respContentType('text/plain');  // кеширование по умолчанию запрещено
    
    http.bodyStr = 'передаваемые данные';
    http.respContentType('text/plain');
    


    void http.respPlainText(String)
    ответ в виде обычного текста

    var body = "?warning&on=" + http.argByKey("on") + " Ok";
    http.respPlainText(body);  // разрешить кеширование (по умолчанию 7 дней)
    // равносильно этому
    http.setBody(body); // можно и так:  http.bodyStr = body;
    http.respContentType('text/plain');  // кеширование по умолчанию запрещено
    


    void http.respJSON(var)
    ответ в виде json

    var obj = {
        date_on_server: new Date(),
        postName:       post.objectName
    };
    http.respJSON(obj, replacer, 2); // аргументы полностью повторяют функционал JSON.stringify()
    http.respJSON(obj);              // объект будет преобразован в json строку и отправлен клиенту
    
    // равносильно этому
    var body = JSON.stringify(obj);
    http.respJSON(body);
    
    // равносильно этому
    http.setBody(JSON.stringify(obj));  // можно и так:  http.bodyStr = JSON.stringify(obj);
    http.respJSON();
    
    // равносильно этому
    http.bodyStr = JSON.stringify(obj); // можно и так:  http.setBody(JSON.stringify(obj));
    http.respContentType('text/javascript');
    
    


    bool http.existFile(String sname)
    отдать файл. Аргументы: sname - это синонем или файл относительно дефолтного каталога (см. секцию post->defDirs файла jcjs.xml ) Если файл не будет найден, то поиск будет продолжен в каталогах (см. секцию server->folders->inc файла jcjs.xml ) В случае успеха возвращает true

    if(http.existFile('stat@favicon.png'))
    {
        http.respFile('stat@favicon.png'))
    }
    else
    {
        if(http.existFile('stat@favicon.ico'))
        {
            http.respFile('stat@favicon.ico'))
        }
    }
    


    bool http.respFile(String sname, bool saveToDisk=false, String contentType='')
    отдать файл. Аргументы: sname - это синонем или файл относительно дефолтного каталога (см. секцию post->defDirs файла jcjs.xml )
    saveToDisk - если true, то браузер откроет диалоговое окно с предложением сохранить файл
    contentType - тип отдаваемых данных. Если не указан, будет выбран автоматически
    Если файл не будет найден, то поиск будет продолжен в каталогах (см. секцию server->folders->inc файла jcjs.xml )
    В случае успеха возвращает true

    if(!http.respFile('stat@favicon.png'))
    {
        http.respFile('stat@favicon.ico'))
    }
    


    bool http.respTmplFile(String &sname, String contentType='')
    обработать шаблон и отдать его клиенту.
    Аргументы:
    sname - это синонем или файл относительно дефолтного каталога (см. секцию post->defDirs файла jcjs.xml )
    contentType - тип отдаваемых данных. Если не указан, будет выбран автоматически
    Если файл не будет найден, то поиск будет продолжен в каталогах (см. секцию server->folders->inc файла jcjs.xml )
    В случае успеха возвращает true

    if(http.respTmplFile('stuff@postsTable/index.html'))
    {
        // Ok
    }
    


    String http.toTitleCase(String)
    Переводит строку к нижнему регистру и первый символ делает заглавым

    var tstr = http.toTitleCase('stRing АБВГД'); // возвратит 'String абвгд'
    


    bool http.existVal(key)
    Проводит проверку наличия аргумента (без учета регистра)

    // запрос '/postsTable/devs/dip/index.html?arg1=val1&arg2=val2&arg3&arg4'
    var exist
    exist = http.existVal('arg1'); // Вернет true
    exist = http.existVal('Arg1'); // Вернет true
    exist = http.existVal('arg5'); // Вернет false
    


    String http.valByKey(key)
    получить значение по ключу ("" - если его нет) (без учета регистра)

    // запрос '/postsTable/devs/dip/index.html?arg1=val1&arg2=val2&arg3&arg4'
    var key
    key = http.argKeyByNum('arg1'); // Вернет 'val1'
    key = http.argKeyByNum('ArG1'); // Вернет 'val1'
    key = http.argKeyByNum('arg5'); // Вернет ''
    


    String http.phpTmpPostFile()
    Этот метод необходим для плагина php-cgi,
    он возвращает имя файла, в котором сохранены POST данные, присланные браузером.
    Работает только если был запрос файла с расширением .php


    arr(String) http.cgiEnvironment()
    Этот метод необходим для плагина php-cgi,
    он возвращает массив строк KEY=VAL
    Что лежит в этом массиве поясняет следующий листинг

    'GATEWAY_INTERFACE=CGI/1.1'
    'DOCUMENT_ROOT=C:/Proj/jCjS2/_dest_dir/stat/'
    'PATH_INFO=/postsTable/'
    'SCRIPT_FILENAME=C:/Proj/jCjS2/_dest_dir/stuff/postsTable/log.php'
    'PATH_TRANSLATED=C:/Proj/jCjS2/_dest_dir/stuff/postsTable/log.php'
    'QUERY_STRING=log=2014-06-08.txt'
    'REMOTE_ADDR=127.0.0.1'
    'REMOTE_HOST=127.0.0.1'
    'REQUEST_METHOD=GET'
    'SCRIPT_NAME=/postsTable/log.php'
    'SERVER_NAME=127.0.0.1'
    'SERVER_PORT=8080'
    'SERVER_PROTOCOL=HTTP/1.1'
    'SERVER_SOFTWARE=jCjS v.2.x.x.xxx - "JavaScript Control - JavaScript Server"'
    'REDIRECT_STATUS=false'
    'PHP_AUTH_USER=Admin'
    'PHP_AUTH_PW=system'
    'Authorization=Basic QWRtaW46c3lzdGVt'
    'Accept=text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
    'Accept-Encoding=gzip,deflate,sdch'
    'Accept-Language=ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4'
    'Connection=keep-alive'
    'Host=localhost:8080'
    'Referer=http://localhost:8080/postsTable/'
    'User-Agent=Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36'
    


    void http.respAuthenticate()
    Отправить запрос на авторизацию


    String http.noCacheName(String sname)

    String http.noCacheId(String sname)
    Сформировать некешируемое имя файла (полезно использовать в html файлах, чтобы облегчить жизнь разработчику)

    var newName = http.noCacheName('/js/jcjsHelper.js'); // Вернет '/js/jcjsHelper.js?5f40cfc0'
    var postfix = http.noCacheId('/js/jcjsHelper.js');   // Вернет 5f40cfc0
    


    arr(String) http.mime_all_lst()
    Функция выводит список всех поддерживаемых типов MIME

    console.log(http.mime_all_lst());
    

    Object http.mime_all()
    Функция выводит список всех поддерживаемых типов MIME в виде js объекта

    console.log(http.mime_all());
    


    String http.mime_name(String fileName)
    Функция выводит Content-Type по имени файла
    Если у файла нет расширения и указан абсолютный путь к файлу,
    то будет произведен анализ внутреннего содержания


    String http.mime_comment(String fileName)
    Функция выводит описание файла
    Если у файла нет расширения и указан абсолютный путь к файлу,
    то будет произведен анализ внутреннего содержания


    String http.mime_suffix(String fileName)
    Функция выводит все возможные расширения к этому типу файла
    Если у файла нет расширения и указан абсолютный путь к файлу,
    то будет произведен анализ внутреннего содержания


    bool http.mime_isText(String fileName)
    Без коментариев


    Object http.mime(String fileName)
    Функция выводит информацию о файле
    Если у файла нет расширения и указан абсолютный путь к файлу,
    то будет произведен анализ внутреннего содержания

    var fname = server.parseSpecialFileName('stat@img/home.png');
    var mime = http.mime(fname);
    console.log(mime);
    /* Выведет в лог
    QVariantMap: {
      "comment": "изображение PNG",
      "name": "image/png",
      "suffix: QVariantList": {
        "0": "png"
      }
    }
    */
    



  • Описание объектов