1. Друзья, в это тяжёлое и непонятное для всех нас время мы просим вас воздержаться от любых упоминаний политики на форуме, - этим ситуации не поможешь, а только возникнут ненужные ссоры и обиды. Это касается также шуток и юмора на тему конфликта. Пусть войны будут только виртуальными, а политики решают разногласия дипломатическим путём. С уважением, администрация Old-Games.RU.

    Скрыть объявление
  2. Если Вы видите это сообщение, значит, вы ещё не зарегистрировались на нашем форуме.

    Зарегистрируйтесь, если вы хотите принять участие в обсуждениях. Перед регистрацией примите к сведению:
    1. Не регистрируйтесь с никами типа asdfdadhgd, 354621 и тому подобными, не несущими смысловой нагрузки (ник должен быть читаемым!): такие пользователи будут сразу заблокированы!
    2. Не регистрируйте больше одной учётной записи. Если у вас возникли проблемы при регистрации, то вы можете воспользоваться формой обратной связи внизу страницы.
    3. Регистрируйтесь с реально существующими E-mail адресами, иначе вы не сможете завершить регистрацию.
    4. Обязательно ознакомьтесь с правилами поведения на нашем форуме, чтобы избежать дальнейших конфликтов и непонимания.
    С уважением, администрация форума Old-Games.RU
    Скрыть объявление

Издевательство над Аяксом

Автор: Helmut · 13 авг 2015 · ·
  1. Ajax - не просто полезная штука, это незаменимая штука. Но нет в мире совершенства. Под каждую задачу нужно писать отдельный скрипт. И если проект достаточно масштабный (у меня - корпоративная система управления предприятием с браузерным интерфейсом), файлы JS начинают разрастаться угрожающими темпами. Разумеется, в процессе работы выявляются закономерности, и более-менее похожие по функциональности элементы стандартизируются. Но все равно, разнообразие остается слишком велико, и непрерывно возрастает при развитии проекта.

    Отсюда возник закономерный вопрос: а можно ли сделать всего одну, но универсальную функцию для бесконечного разнообразия задач? Не, я в курсе, что наверняка есть какие-нибудь фреймворки, но интереснее же придумать и сделать самому. К тому же никогда не любил фреймворки, все они в чем-то да ограничены.

    После некоторых размышлений в голову пришла концептуальная идея: перенести основной функционал со стороны клиента на сторону сервера. Очевидно, что среверные скрипты (в моем случае - на языке Perl), предоставляют неизмеримо большую гибкость. К тому же и без того по определению пишутся под конкретные функции с переменными параметрами. Так пусть заодно и определяют и обработку своего результата на стороне клиента. В результате задача сформировалась следующим образом: необходим способ разметки пакета HTTP, чтобы универсальная функция на стороне клиента могла вызвать любой серверный скрипт, передать ему любые необходимые параметры и интерпретировать его ответ.

    В результате получился следующий формат вывода результатов работы серверных скриптов. Можно расширять и углублять дальше, если потребуется. На данный момент сделана возможность обращения не только по ID, добавлена подпрограмма для обработки innerHTML выпадающих списков SELECT, создающая новые элементы списка через конструктор.

    Как нетрудно заметить, свойства, обрабатываемые жабаскриптом в порядке object.property=value, типа innerHTML или className поддерживаются все, т.к. не требуют исключений. Из исключений, требующих отдельной функции, на данный момент обрабатываются свойства style, classList и setAttribute, а также передача файлов и установка cookies, так что в плане разметки обращение к ним ничем не отличается от работы с любыми другими элементами и свойствами.

    Список свойств указывается в виде свойство="значение", разделенных пробелами, запятой или точкой с запятой. Если значение содержит только буквенно-цифровые символы и символ подчеркивания, кавычки можно опустить, в противном случае следует использовать одинарные или двойные кавычки.

    Пример вывода результатов серверным скриптом:
    Код:
    print '<SPLIT target="div1" property="innerHTML">';
    print $text1;
    print '<script target="div1" property="before">alert(\'alert1\')</script>';
    
    print '<SPLIT target="div1_class" method="getElementsByClassName" property="style">';
    print 'width=100px';
    print 'background-color="#ffffff" padding="20px 5px";
    
    print '<SPLIT target="input1" property="value" noclear>';
    print $text2;
    
    print '<SPLIT target="select1" property="innerHTML">';
    print qq '<option value="$arr[$e][1]">$arr[$e][7]</option>';
    print qq '<option selected value="$arr[$e][1]">$arr[$e][7]</option>';
    
    print '<SPLIT target="select1" property="className">';
    print 'class1';
    print '<script target="input1">alert(\'alert2\')</script>';
    print '<script>alert(\'alert3\');alert(\'alert4\')</script>';
    
    print '<SPLIT target="select1" property="classList">';
    print 'add=newclass delete=oldclass toggle=class_2';
    
    print '<SPLIT target="select1" property="setAttribute">';
    print 'src="aaa.bbb.ru"';
    
    my $ctime = time + 600; #время актуальности +- секунды
    print "<cookie name='sid' value='$cookie' expires='$ctime'>";
    print "<cookie name='sim' value='Test' expires='$ctime'>";
    
    И так далее, все согласно HTML. Очевидно, что в результате над тремя элементами с указанными ID будут выполнены определенные действия, кроме того, в определенном порядке будут выполнены 3 вызова жабаскрипт-функций. Все действия выполняются пообъектно, т.е. в том порядке, в котором происходит первое обращение к данному ID. Если вы сперва изменили содержимое элемента 1, потом содержимое элемента 2, в потом к элементу 1 добавили новый стиль, фактически в результате сперва выполнятся все действия с элементом 1, а потом с элементом 2.
    С яваскрипт-функциями аналогично. Если не задано принудительное изменение очередности, то все они будут выполняться после выполнения всех действий с HTML, в той последовательности, в котором были написаны.

    <SPLIT>
    method - необязательный параметр, указывает метод выборки элементов. По умолчанию - getElementById. Поддерживаются методы getElementsByTagName, getElementsByName, getElementsByClassName, querySelector и querySelectorAll.
    target - обязательный параметр, указывает ID элемента или условия для поиска согласно выбранному методу.
    property - обязательный параметр, указывает изменяемое свойство элемента.
    noclear - необязательный параметр, Его наличие указывает, что в свойствах innerHTML и value результат будет дополняться к уже существующему, а не заменять его. Параметр задается (если нужен) при первом обращении к ID, в не зависимости от свойства.
    Есле в теле одного ответа содержится несколько обращений к одному свойству одного элемента, то все они в любом случае будут просуммированы. А общий результат, если это innerHTML или value, будет либо дополнен к имеющемуся, либо заменит его, в зависимости от параметра noclear.

    <SCRIPT>
    target - необязательный параметр (ID элемента). По умолчанию notarget. Привязывает очередность выполнения функции к действиям с элементом с указанным ID.
    property - необязательный параметр (before/after). По умолчанию after. Указывает, будет эта функция выполняться перед действиями с указанным элементом или после. Если стоит before, но не указан target, будет выполняться в самом начале.

    <cookie>
    Внутри тега задается список параметров видп имя=значение. Пример есть выше. Name и value = обязательные параметры, expires задается в UnixTime в секундах.

    Функция запроса вызывается следующим образом:
    SendURL(url, form, aspect);
    url - обязательный параметр, адрес вызываемого серверного скрита. Может содержать дополнительные параметры стандартного вида GET. Например: ('cgi/function.cgi?action=1&option='+this.value).
    form - необязательный параметр, имя формы (FormName), данные из которой будут собраны и присоединены к запросу, если указанная форма существует. Может быть указано несколько форм в виде массива [].
    aspect - необязательный параметр (1/0), по умолчанию 0. Определяет параметр запроса, 0 - асинхронный, 1 - синхронный.
    Пример вызова:
    Код:
    SendURL(('cgi/function.cgi?action=1&option='+this.value), 'MyForm', 1);
    Сама функция

    Поскольку POST создается в виде объекта, чтобы в него можно было засунуть файлы и куки, что в обычном состоянии Аякс не позволяет, ссылаясь на безопасность, на стороне CGI-скрипта чтение нужно делать комбинированным: GET читать как обычно, через переменные окружения, а вот POST через CGI->param.

    Код:
    use CGI ':standard';
    
    my $buffer = $ENV{'QUERY_STRING'};
    my @pairs = split(/&/, $buffer);
    foreach $pair(@pairs) {
        my ($name, $value) = split(/=/, $pair);
        $value =~ tr/+/ /;
        $value =~ s/%([a-fA-F0-9][a-fA-f0-9])/chr(hex($1))/eg;
        $input{$name} = $value;
    }
    for my $name (CGI::param()) {
        for my $value (scalar CGI::param($name)) {
            $input{$name} = $value;
        }
    }
    

Комментарии

  1. Helmut
    @Steel Rat, Я тоже. Но давно уже таких заказов не попадалось. Даже бухи - и те хотят общую БД.
  2. Steel Rat
    @Helmut, не знаю, я ваще онлайн не люблю. Только сингл, только хардкор!
  3. Helmut
    @Steel Rat, не, меня только бухгалтерские задачи доводят до алкоголизма. А так - разница только в интерфейсе. Делать вендовый output или юзать браузер - какая разница?
  4. Steel Rat
    @Helmut, веб-программирование. Оно навевает на меня грусть и тоску.
      Goblinit нравится это.
  5. Helmut
    @Steel Rat, а тебе что не нравится?
  6. Steel Rat
    Плакать хочется.
  7. Deep_wolf
    У нас в городе ларек с таким названием есть, там игрушки продают. Тоже мимо.
  8. Helmut
    *trollface*
  9. Mel Shlemming
    Блин, я думал тут про футбол... :(
      Steel Rat, Sharp_ey, пепяка и 2 другим нравится это.
Чтобы оставить комментарий просто зарегистрируйтесь и станьте участником!
  1. На этом сайте используются файлы cookie, чтобы персонализировать содержимое, хранить Ваши предпочтения и держать Вас авторизованным в системе, если Вы зарегистрировались.
    Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie.
    Скрыть объявление