WWW,CGI-специфика
Q: Я положил скрипт на сервер, ввожу его путь в браузер, но вместо того,
чтобы выполнять скрипт, браузер выводит его исходный текст.
A: Чтобы сервер запускал скрипт и выдавал результаты его работы, необходимо
объяснить серверу, что этот файл -исполняемый. Существующее в
unix-системах понятие "атрибуты файла" отличается от атрибутов в DOS/Windows,
и в unix исполняемый файл определяется не расширением, а атрибутом.
Если сервер работает на unix-системе, необходимо проставить на
файлатрибуты исполняемого файла. Это делает команда "chmod 0755 file",
если вы работаете через telnet или ssh, или же продвинутый FTP-клиент типа
CuteFTP или FAR ftp plugin. Атрибуты файла, который могут исполнять
все желающие (в том числе и сервер), выглядят в буквенном представлении, как
-rwxr-xr-x
Если вы работаетев win32 среде, достаточно определить программу,
запускающую файлы с расширением, которое вы даете скриптам - например, cgi.
Для этого нужно в windows explorer'е дважды кликнуть по файлу .cgi, и
выбрать perl\bin\perl.exe в качестве запускающей программы.
Q: При попытке запустить скрипт происходит 500 Internal Server Error! Что это за
ошибка?
A: Это, строго говоря, просто сообщение об одной из ошибок, приведших к
невозможности нормального выполнения скрипта. Узнать что же привело к этому можно в большинстве случаев из логов сервера.(*)
Чаще всего возникает в следующих случаях:
1) в первой строке отсутствует или неправильно указан путь к perl. обычно это
#!/usr/local/bin/perl или #!/usr/bin/perl
2) Файл со скриптом содержит DOS-овые концы строк 0x0D 0x0A. В юниксе конец
строки- только 0x0A. Чтобы исправить это, воспользуйтесь соотв. возможностью
редактора FAR(shift-f2, asUnix text), или призакачке скрипта на ftp
используйте ASCII-режим вместо бинарного.
3) Скрипт невыводит ничего во время работы, или не выводит заголовок.
Hеобходимо, чтобы он выводил хотя бы content-type заголовок, например:
print "Content-type: text/html\n\n";
print "Ok";
Обратите внимание на двойной перевод строки в конце заголовка.
(*)Примечание:
Если у вас нет доступа к логу ошибок сервера, для отладки скрипта используйте
директиву use CGI::Carp qw (fatalsToBrowser); В этом случае при фатальной ошибке, приводящей к завершению скрипта, эта ошибка будет видна вам в браузере.
Q: Как узнать IP человека, вызвавшего скрипт?
A: $ENV{'REMOTE_ADDR'}
Q: Как узнать, с какой страницы идет ссылка на скрипт?
A: $ENV{'HTTP_REFERER'}
Q: Как узнать IP прокси, если через нее запустили скрипт?
A1 $ENV{'HTTP_VIA'}
A2: Hекоторые прокси добавляют в конец заголовка строку типа
", via ProxyName", и в результате вместо переменной HTTP_VIA эту строку можно
наблюдать в конце переменной $ENV{'HTTP_USER_AGENT'}
Q: А можно ли узнать IP юзера, запустившего скрипт через прокси?
A: $ENV{'HTTP_X_FORWARDED_FOR'}. Hо не все прокси обеспечивают IP сидящего за
ними юзера. "Честные" прокси,- у провайдеров, например,- это делают. А
некоторые халявные (анонимные) прокси-сервера, могут и не показывать IP сидящего "за" ними пользователя.
Q: А какие еще значения есть у этого %ENV ?
A: for (keys %ENV) { print "$_ = ${ENV{$_}}\n" }
A1: То же самое, но по-другому записанное (более "перловое" решение):
print join("
",map("$_ = $ENV{$_}", keys %ENV));
Q: Как запускать скрипт на сервере через определенные промежутки времени, или
в определенное время суток, день недели, месяц?
A: Это возможно, если есть шелл-доступ на сервер. Читайте man crontab
Q: Как, зная ip, получить имя (DNS), за которым этот ip закреплен?
A: Встроенная функция gethostbyaddr()
Q: Что такое method GET, и что такое method POST?
A1: rfc2616
A2: GET - передача параметров скрипту из строки location браузера. Пример:
script.cgi?mode=aa&type=bb&length=12
Минусы этого метода:
1. Все параметры видны в строке. Если в кач-ве параметров передается пароль
- получается дырка в безопасности
2. Длина данных, передаваемых таким методом, ограничена.
3. Hельзя передавать multipart form data, в т.ч. файлы через кнопочку
"Browse"
POST - передача данных скрипту через STDIN. Отсутствуют минусы метода GET.
Обычно метод GET используется, когда скрипт вызывается со страницы через линк
, а POST - при нажатии кнопки submit в форме.
О получении параметров внутри скрипта читайте в следующем Q.
Q: Как обрабатывать параметры, переданные скрипту?
A1: Используйте модуль CGI. Прочтите perldoc CGI , а для начала простой
пример:
use CGI;
$q=new CGI();
$mode=$q->param('mode');
$q - объект, который имеет несколько методов и полей, относящихся к
параметрам вызова, переменным окружения, cookie, и пр. В $mode содержится значение параметра 'mode'.
или проще: use CGI qw/:standard/;
$mode=param('mode'); если вам не нужно несколько объектов.
A2: Некоторые предпочитают пользоваться библиотекой cgi-lib (она тоже входит в модуль CGI, хотя существуют индивидуумы, которые включают ее отдельным файлом).
Пример:
use CGI qw(:cgi-lib);
ReadParse(); #Функция возвращает все параметры в хэш.
$mode=$in{'mode'};
A3: Можно пойти по пути изобретения велосипеда и начать переписывать модуль CGI, т.е. разбор параметров метода GET, потом наверняка понадобиться POST, а потом multipart form data. В написанный код закрадуться ошибки, которые придется отлавливать на последующих этапах. Это конечно дает неплохую практику программирования, но лучше просто посмотрите как написан модуль CGI.
(Высказанное в последнем ответе является тем самым ИМХО ).
Q: Посоветуйте халявный хостинг с поддержкой CGI-perl.
A:
Примечание:
В последнее время почти все халявные хостинги перестали поддерживать исходящие запросы, т.е. скачать откуда-нибудь файл используя LWP или Net::Ftp не получиться.
Если знаете хостинг с поддержкой исходящих запросов, напишите мне, буду благодарен.
Q: Что надо указатьв заголовках HTTP-ответа CGI скрипта, выводящего
содержимое, которое надо не показать на экране, а сохранить в файле с заданным
именем, например 'download.zip' ? А то браузер сохраняет файл с именем скрипта.
A: print "Content-Type: application/octet-stream\nContent-Length: ", -s 'download.zip' ,"\n";
print "Content-Disposition: attachment; filename=download.zip\n\n";
Q: Директивы SSI не обрабатываются в выводе скрипта. Что делать?
A: Есть специальный модуль - CGI::SSI.