Шаг 151.
Передача информации CGI-программе

    На этом шаге мы рассмотрим особенности передачи информации на сервер.

    Как мы уже знаем, существуют два метода кодирования информации, содержащейся в форме:

Второй метод нужен только в том случае, если к содержимому формы присоединяется локальный файл, выбранный при помощи элемента формы <INPUT TYPE=FILE>. В остальных случаях следует использовать метод кодирования по умолчанию.

    Схема кодирования application/x-www-form-urlencoded одинакова для обоих методов пересылки GET и POST и заключается в следующем.

    Для каждого элемента формы, имеющего имя, заданное атрибутом NAME, формируется пара "name=value", где value - значение элемента, введенное пользователем или назначенное по умолчанию. Если значение отсутствует, соответствующая пара имеет вид "name=". Для радиокнопок и переключателей используются значения только выбранных элементов. Если элемент выбран, а значение атрибута VALUE не определено, по умолчанию используется значение "ON".

    Все пары объединяются в строку, в качестве разделителя служит символ &. Так как имена и значения представляют собой обычный текст, то они могут содержать символы, недопустимые в составе URL (метод GET пересылает данные как часть URL). Такие символы заменяются последовательностью, состоящей из символа % и их шестнадцатеричного ASCII-кода. Символ пробела может заменяться не только кодом %20, но и знаком + (плюс). Признак конца строки, встречающийся в поле TEXTAREA, заменяется кодом %0D%0A. Такое кодирование называется URL-кодированием.

    Закодированная информация пересылается серверу одним из методов GET или POST. Основное отличие заключается в том, как метод передает информацию CGI-программе.

    При использовании метода GET данные формы пересылаются серверу в составе URL-запроса, к которому добавляются после символа ? (вспомним, что запрос - это формализованный способ обращения браузера к Web-серверу). Тело запроса в этом случае является пустым. Для формы из примера предыдущего шага запрос выглядит следующим образом:

GET /cgi-bin/registrar.cgi? regname=bob&passwordl= rumata&password2=rumata&
age=lt20&language=russian&format= HTML&wish=%F6%C5%CC%Dl%DA%CE%D9 HTTP/1.0
'
' (заголовки запроса, сообщающие серверу информацию о клиенте) 
'
<пусто>      (тело запроса)

    Часть URL после символа "?" называется строкой запроса. Web-сервер, получив запрос, присвоит переменной среды QUERY_STRING значение строки запроса и вызовет CGI-программу, обозначенную в первой части URL до символа "?":

  /cgi-bin/registrar.cgi  
CGI-программа registrar.cgi сможет затем обратиться к переменной QUERY_STRING для обработки закодированных в ней данных.


    Замечания.
  1. Обратите внимание на то, что данные, введенные в поле типа PASSWORD, передаются открытым текстом без шифрования. При передаче данных методом GET они в составе URL помещаются в файл регистрации доступа access.log, обычно открытый для чтения всем пользователям. Таким образом "секретные" данные, введенные в поле типа PASSWORD, оказываются доступными посторонним.

  2. Метод GET позволяет передавать данные CGI-программе вообще без использования форм. Информацию, содержащуюся в приведенном выше URL, можно передать при помощи следующей гиперссылки, помещенной в HTML-документ:
      <А HREF="http://www.domain/cgi-bin/registrar.cgi?regname= bob&
      password1=rumata&password2=rumata&age=lt20&language=russian&
      format=HTML&wish=%F6%C5%CC%Dl%DA%CE%D9">CGI-программа</А>,
    
    заменив в этом фрагменте символ "&" его представлением & или & для правильной интерпретации браузером.

        К сожалению, эта информация является статической. Форма же позволяет менять данные.

        Строка запроса - не единственный способ передачи данных через URL. Другим способом является дополнительная информация о пути (extra path information), представляющая собой часть URL, расположенную после имени CGI-программы. Сервер выделяет эту часть и сохраняет ее в переменной среды PATH_INFO. CGI-программа может затем использовать эту переменную для извлечения данных. Например, URL

       http://www.domain/cgi-bin/registrar.cgi/
       regname=bob&password1=rumata&password2=rumata&age=lt20&language=
       russian&format=HTML&wish=%F6%C5%CC%Dl%DA%CE%D9
    
    содержит уже знакомые нам данные, но не в виде строки запроса, а в виде дополнительной информации о пути. При получении запроса с таким URL сервер сохранит данные в переменной среды
      PATH_INFO= "/regname=bob&password1=rumata&password2=rumata&
      age= lt20&language=russian&format=HTML&wish=%F6%C5%CC%Dl%DA%CE%D9"
    
    Название объясняется тем, что обычно этим способом передается информация о местоположении какого-либо файла (extra path information). Например, URL
      http://www.domain/cgi-bin/registrar.cgi/texts/jdk_doc.txt
    
    содержит дополнительную информацию PATH_INFO="/texts/jdk_doc.txt" о местонахождении файла jdk_doc.txt относительно корневого каталога дерева документов. Другая переменная среды PATH_TRANSLATED содержит информацию об абсолютном местоположении файла в файловой системе, например,
      PATH_TRANSLATED="/home/httpd/docs/texts/jdk_doc. txt"
    
    а переменная DOCUMENT_ROOT содержит путь к корневому каталогу дерева документов, в нашем случае DOCUMENT_ROOT="/home/httpd/docs/".

    При использовании метода POST данные формы пересылаются серверу в теле запроса. Если в примере предыдущего шага вместо метода GET использовать метод POST

  <form method="post" action="/cgi-bin/registrar.cgi">,
то запрос клиента будет иметь следующий вид:
POST  /cgi-bin/registrar.cgi HTTP/1.1
'
' (заголовки запроса,   сообщающие  серверу информацию о клиенте)
'
Content-length:   126
regname=bob&password1=rumata&password2=rumata&age=lt20&
language=russian&format=HTML&wish=%F6%C5%CC%Dl%DA%CE%D9

    В этом фрагменте среди прочих заголовков выделен заголовок Content-length, сообщающий серверу количество байт, переданных в теле запроса. Это значение сервер присваивает переменной среды CONTENT_LENGTH, а данные посылает в стандартный ввод CGI-программы.

    Методы GET и POST имеют свои достоинства и недостатки. Метод GET обеспечивает лучшую производительность при пересылке форм, состоящих из небольшого набора коротких полей. При пересылке большого объема данных следует использовать метод POST, так как браузер или сервер могут накладывать ограничения на размер данных, передаваемых в составе URL, и отбрасывать часть данных, выходящую за границу. Метод POST, к тому же, является более надежным при пересылке конфиденциальной информации.

    На следующем шаге мы рассмотрим CGI-сценарии.




Предыдущий шаг Содержание Следующий шаг