Учебное пособие по CGI-программированию

Анимация

Когда говорят о каком-то популярном сайте,то частенько к преимуществам относят и анимацию. Действительно,когда изображение изменяется (и особенно к месту ;)),то это смотритс и пользователю нравится.

Говоря об анимации нужно сразу отметить что нет лучшего способа. Анимацию можно сделать ДЕСЯТКАМИ Способов,каждый хорош в своей области применения. Я перечислю только некоторые из них,которые чаще всего применяются:

Самый простой,но наименее функциональный способ это GIF с анимацией.

Потом можно воткнуть анимационный файл MPEG или AVI они более отражают суть анимации, но имеют недостаток,что для проигрывания их на некоторых браузерах нужны специальные подключаемые модули.К тому же они не интерактивны.

Можно реализовать анимацию в рамках Java-апплета,когда апплет находясь на страничке сам перерисовывается со временем.

Таким же интерактивным средством служит обращение к массиву document.images[] из JavaScript.Достоинство-помимо интерактивности,полная интегрированость с HTML -станичкой.Но может как и предыдущий использоваться только с относительно новыми браузерами,которые поддерживают Java и JavaScript.

В общем в каждом случае выбор остается за вами.Вам решать насколько тот или иной способ хорош в вашей ситуации.Я же познакомлю вас с еще одним.

Вы даже уже были знакомы с этим способом,когда я вам рассказывал о nph- скриптах Теперь когда вы уже так много знаете,можно модифицировать тот , добавив в него вызов картинки по случайному принципу:
#!/usr/bin/perl #nph-animate2.cgi $delay=3; @files = qw(img0.gif img1.gif img2.gif img3.gif);
select (STDOUT); $|=1; #autoflush mode on #Generate header print "HTTP/1.0 200 Okay\n"; print "Content-Type: multipart/x-mixed-replace;boundary=myboundary\n\n"; srand; print "--myboundary\n"; while(1){ $file=$files[int(rand($#files))]; #random file print "Content-Type: image/gif\n\n"; open(PIC,"$file"); print ; close(PIC); print "\n--myboundary\n"; sleep($delay); }

Конечно одно из самых примитивных применений такой системы.Более мощным примером могло бы послужить отслеживание на сервере какого-нибудь периодически изменяющегося файла и пересылка пользователю обновленной версии.

Такая Система применяется например в Чате,при появлении новых сообщений. Чатовая система достаточно сложна для этого пособия и я не стал сюда ее включать.Однако,если вам очень интересно,то я с удовольствием пришлю ее вам.

Генерация ответа

Большую часть того что нужно знать о генерации ответа,я сказал в разделе .Нет,не угадали! Я не буду сдесь говорить о всяком дизайне того что вы выдаете.Этому вы успели напрактиковатся на HTML -страничках.

Я поговорю о MIME (Multipurpose Internet Mail Extension).И о разных браузерах.

Стандарт MIME появился в электронной почте (e-mail) потому что остро стала проблемма пересылки по e-mail различных данных в различных форматах.Так как HTTP тоже работает с различными типами данных то поэтому тоже использует MIME для своих нужд. Типы MIME состоят из Типа и подтипа (например text/plain,где text-указывает на наличие текстового содержимого,а plain-уточняет его как простой текст) приведеный ниже список (он далеко не полн,типов MIME огромное количество) описывает некоторые часто встречающиеся типы.: text/htmltext/plain text/richtext image/gif image/jpeg image/tiff audio/basic audio/32kadpcm audio/ video/mpeg video/quicktime multipart/mixed multipart/alternate multipart/ application/octet-stream application/msword application/postscript message/digest
Информация о MIME больше возможно пригодится вам в том случае если вы собираетесь работать из ваших скриптов с электронной почтой,но и для WWW она не повредит. Особенно знание Content-Type:

Content-Type:

Состоит из типа и подтипа типы могут быть как стандартные так и экспериментальные начинающиеся с префикса 'x-':

text

Текстовые данные.Первым подтипом который включен сюда это plain,что значит простой текст. сюда же включен самый ходовой формат html .У типа text как и у многих типов могут быть параметры,главным из них является charset он как раз и указывает на раскладку символов, которая применена в тексте, так что если вы хотите указать браузеру какую раскладку применять, то просто укажите charset:

Content-Type: text/plain; charset=us-ascii


Content-Type: text/html; charset=iso-8859-1

Content-Type: text/html; charset=koi8-r

multipart

Данные которые могут состоять из нескольких частей,различных типов данных.Поэтому параметром multipart служит boundary, позволяюший указать разделитель.Каждый фрагмент в многочастевом сообщении имеет свой Content-Type: (Он может быть также multipart,т.е. допускаются вложеные multipart,главное чтоб boundary были разными).В электронной почте применяется больше multipart/mixed (основной подтип) и multipart/alternative (Он отличается тем что показывается одна из альтернатив,например сообщение шлется в простом и HTMLом форматах,и почтовая программа показывает либо часть,которую она способна отобразить). В WWW -програмировании распостранен x-mixed-replace ,который означает что следующая часть должна заменить предыдущую после подгрузки, что применяется для анимации().

Теперь о разделителе,его надо выбирать так,чтоб он не встретился где-то в данных (т.е. что-то вроде "diUr344rnmvforgefvrg923rghyj2").Когда вы задали разделитель,например boundary="boundary" то когда закончилась одна часть,вы должны выдать строку --boundary,последн часть --boundary--,причем эти разделители должны быть на отдельной строке,а не сливаться с текстом:

Пример:



MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="w23renff491nc4rth56u34-9449"

--w23renff491nc4rth56u34-9449 Content-Type: text/plain; charset="koi8-r"

Hello,World!! --w23renff491nc4rth56u34-9449 Content-Type: text/html; charset="us-ascii"

Hello,Word!!


Hello people! --w23renff491nc4rth56u34-9449--


message

Представляет инкапсулированое почтовое сообщение.Используется в e-mail ,а не в WWW.

image

Некоторое Графическое изображение.(чаще всего image/gif и image/jpeg)

audio

Аудиоданные.

video

Видеоданные.

application

бинарные данные какого-нибудь приложения.В том случае если данное приложение может быть запущено,Браузер запускает его.Например при поступлении данных application/msword Браузер спросит,нужно ли запустить Word для просмотра досумента.При отсутствии нужного приложения браузер спросит в каком файле сохранить данные.Подтип octet-stream как раз и означает поток байт информации,который и используется по умолчанию.(К сожалению не все так гладко,известен глюк в Netscape Navigator'е который вместо того чтоб сохранить application/octet-stream


пытается его показать как text/plain что если это сгенерировано из CGI,ни к чему хорошему не приводит ;(()

Что касается application ,то Вы можете тут смело извращатся,используя x- типы данных,

Например application/x-fuck-to-netscape-navigator. ;)))))

Часто используемый параметр name позволяет указать имя файла.Например:

Content-Type: application/msword; name="readme.doc"

Что полезно при полученнии файлов через HTTP,причем этот параметр может применятся и для других типов таких image или audio ,Например:

Content-Type: image/gif; name="myfoto.gif"

Content-Transfer-Encoding:

Применяется больше в системе электронной почты и обозначает метод кодирования, которым были закодированы данные при передаче сообщения.Например:

7bit 8bit quoted-printable base64 binary x-типы

MIME-Version:

Указывает версию MIME .

Теперь поговорим о разных браузерах вы знаете что браузеры бывают разные,разных версий на разных платформах, поддерживают и не разные тэги и глюки у них тоже разные.....;((( .

Это могло попортить много нервов WEB-дизайнерам и конечно же нам ,CGI-програмистам. Профессионально написаный сайт от просто хорошего отличается тем что хорошо выглядит Не только на экране того браузера,которым пользуется сам его автор,а на других тоже.

Если вы используете JavaScript для своих страничек,то вы уже наверно использовали (или хотя бы вам в голову приходила мысль использовать)свойства navigator.AppName navigator.AppCodeName navigator.appVersion navigator.userAgent:



или
Your Name:
Your age:



Ну вот , на этом можно закончить это краткое введение в HTMLые формы.

Итак,У нас на входе скрипта данные формы,закодированые методом Положеные в Переменную QUERY_STRING или подаваемые на STDIN.Мы должны вопервых их получить.

if($ENV{'REQUEST_METHOD'} eq 'GET'){#Анализируем метод,GET или POST $query=$ENV{'QUERY_STRING'}; } elsif($ENV{'REQUEST_METHOD'} eq 'POST'){ sysread(STDIN,$query,$ENV{'CONTENT_LENGTH'}); }


Вот,мы уже считали наш запрос в переменную $query.Теперь пришло самое время ее обработать. Мы знаем что поля разделены символом '&' значит используем его в качестве разделителя функции split:

@formfields=split(/&/,$query);


Вот разделили,а теперь организуем цикл foreach по полученым полям @formfields



foreach(@formfields){ if(/^Name=(.*)/){$name=urldecode($1);} if(/^Age=(.*)/){$age=urldecode($1);} }


Сдесь выражение в регулярном выражении в круглых скобках (.*) после знака '=',запоминаетс в скалярную переменную $1 ,которая затем и декодируется нашей старой и знакомой функцией urldecode (я предупреждал,что она будет почти в каждой вашей CGI-программе)

sub urldecode{ #очень полезная функция декодировани local($val)=@_; #запроса,будет почти в каждой вашей CGI-программе $val=~s/\+/ /g; $val=~s/%([0-9a-hA-H]{2})/pack('C',hex($1))/ge; return $val; }


Так мы проходим по всем полям,которые нам переданы.Это стандартный подход,он годится в качестве шаблона.У вас может возникнуть вопрос,а что делать если вам переданы данные от списка у которого задана возможность выбора нескольких элементов и данные поступают в таком виде: Sel=opt1&Sel=opt2&Sel=opt9. Тут тоже нет никаких проблем,просто запихиваем эти поступающие значения в массив.

foreach(@formfields){ ..... if(/^Sel=(.*)/){push @Sel,urldecode($1);} ..... }


И потом спокойно оперируем с Полученым Массивом @Sel.

На этом можно так сказать заканчивается шаблонная часть скрипта и начинается содержательная, которая зависит только от вашей фантазии.....

Вы можете сколько угодно анализировать полученые значения,обращатся при этом к различным файлам .Если вы к этому приложите фантазию,то кто знает что получится....


А Пока Ради примера я вам напишу скрипт, который ведет социологическое исследование насчет курения и отношения к нему.Может он слишком массивен для данного пособия, но зато он наглядно показывает как достаточно простыми средствами можно проводить социологические исследования.