Ваша CGI-программа ожидает параметры запроса.Параметры запроса - это (необязательные) биты URL, которые появляются после ?
.Поэтому в URL-адресе, который выглядит следующим образом:
https://example.com/cgi/your_program.cgi?foo=1&bar=2
Параметры запроса: foo=1&bar=2
.
Внутри CGI-программы вы получаете доступ к параметрам запроса, анализируя их из $ENV{QUERY_STRING}
,Это то, что делают первые несколько строк вашей программы.
Но что происходит, если ваша программа вызывается так:
https://example.com/cgi/your_program.cgi
Тогда нет параметров запроса и в них ничего не будет$ENV{QUERY_STRING}
.Вот что генерирует предупреждение (и это предупреждение, а не ошибка), которое вы видите.В строке 4 вы пытаетесь разделить $params
, но в $params
нет данных.Ваша программа должна иметь дело с тем случаем, когда ей передаются никакие параметры.
Но это не то, что убивает вашу программу.Как я уже сказал, это предупреждение, а не ошибка.Ошибка вызвана другой проблемой.
Программа CGI должна возвращать две вещи - набор заголовков и некоторый контент.Вы, очевидно, знаете, что большая часть вашего кода связана с печатью заголовков и контента.Но что происходит, когда нет параметров?Поскольку $params
пусто, @tokens
также не будет содержать данных.Это означает, что ваше тело цикла foreach
никогда не выполняется и заголовок не возвращается.
Могу поспорить, что журнал ошибок вашего веб-сервера содержит что-то вроде «заголовки не найдены».
Еще несколько вещей, которые следует учитывать:
- Всегда добавляйте
use strict
и use warnings
к вашему Perl-коду.И исправьте обнаруженные проблемы (наиболее очевидной из них будет необходимость объявить все ваши переменные, используя my
). - Пожалуйста, подумайте об использовании CGI.pm для анализа ваших параметров и создания ваших заголовков.В этом есть сложности, которые вы не учли.Люди, написавшие модуль, рассмотрели их.
- Программа CGI должна излучать ровно один набор заголовков.Так что помещать заголовки в цикл, который может быть выполнен ноль раз (как мы делаем сейчас) или несколько раз, кажется странным.Возможно, вы захотите пересмотреть эту логику.
- Получение ввода от пользователя (например,
range
) и передача его непосредственно команде операционной системы - это путь к катастрофе.Пожалуйста, убедитесь, что вы очистили ввод пользователя перед тем, как использовать его таким образом.