Выбрать главу

Рис. 29.7. Форма cgi, использующая метод get

Теперь выполним ввод и отсылку некоторой информации (рис. 29.8). После щелчка на кнопке 'Send it' отображается страница, показанная на рис. 29.9. Значение переменной QUERY_string отображается только частично по причине большой длины строки. Ниже приведена строка, имеющая полную длину:

contact=David+Tansley&f ilm=The+So_md+Of+Music&actor=Bruce+Willis&view_cine=onS,view_vid=onbtextarea=%21%22%A3%A3%24%25 %24%25%5E*%5E%26*%28%29*%2 8%29%28*%OD%OAHow%27s+that+%21%21

Рис. 29.8. Выбор и ввод информации в форму

Рис. 29.9. Информация, отправленная формой, закодирована

Для пересланной информации необходимо иметь следующие поля, присвоенные

переменной query string, показанной выше:

Переменная Значение переменной
contact David Tan$1ey
film The Sound of Music
actor Bruce Willis
view cine Если установлено значение on, то флажок выбран
view_vid Если установлено значение on, то флажок выбран
textarea !"%$%А*А&*о*о(*
How's that it!

Декодирование закодированной строки

После того как пользователь щелкнет на кнопке "submit", информация присваивается переменной query_string, а строка кодируется следующим образом: • Все пробелы заменяются знаками +.

   •  Все поля значений разделяются символами &.

   • Все значения и соответствующие поля разделяются знаками =.

   • Все символы и некоторые специальные символы представляются кодами %ху, где xy является шестнадцатеричным эквивалентом данного символа. При просмотре переменной QUERY_STRING можно заметить, что многие из этих символов представлены переменной textarea.

Протокол cgi определяет, что любые символы в форме %ху (где xy является шестнадцатеричным числом) могут быть преобразованы в эквивалентные символы ASCII. Эти шестнадцатеричные символы состоят из специальных символов &, %, +, =, (, ) и всех других символов, выходящих за рамки десятичного диапазона ASCII с границей 127. Например, символу ( соответствует эквивалент в виде %29.

Шестнадцатеричные символы создаются в том случае, когда пользователь вводит значения в свободные текстовые поля. Однако эти символы могут также являться частью выбранного текста меню. Для выполнения декодирования закодированной строки нужно выполнить следующее:

   • заменить все символы & символами перевода строки;

   • заменить все символы + пробелами;

   • заменить все символы = пробелами;

   • преобразовать все значения %xy в эквивалентные символы ASCII.

После завершения описанной выше последовательности действий должна быть возможность осуществить запрос или реализовать доступ к каждой переменной. Благодаря этому можно обрабатывать отсылаемую информацию. В ходе декодирования выполняется только половина работы, хотя и наиболее трудоемкая. Для обеспечения доступа к значениям переменных можно воспользоваться командой eval.

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

$ pg conv.cgi

#!/bin/sh

#сценарий conv.cgi

#декодирование строки URL

echo "Content‑type: text/html"

echo ""

echo "<HTML><PRE>"

#отображение метода кодированной строки

echo "Method : $REQUEST_METHOD"

echo "Query String : $QUERY_STRING"

echo "<HR>"

#применение редактора sed для замены символов & символами табуляции

LINE=`echo $QUERY_STRING | sed 's/&/ /g'`

for LOOP in $LINE do

# разбивка на поля NAME и TYPE

NAME=`echo $LOOP | sed 's/=/ /g' | awk '{print $1}'`

#получение TYPE, замена всех символов=пробелами, a %hex_num - \xhex_num

#замена всех символов + пробелами

TYPE=`echo $LOOP | sed 's/=/ /g' | awk '{print $2}' | \ sed -e 's/%\(\)/\\\x/g' | sed 's/+/ /g'`

#используется функция printf, которая отображает значения переменных:

#после завершения преобразований шестнадцатеричных значений

printf "${NAME}=${TYPE}\n"

#в переменную VARS записываются значения отдельных полей, которые затем

#передаются команде eval, благодаря чему отдельные поля можно адресовать;

#при этом, если поля содержат пробелы, требуется удвоенная обратная косая черта

VARS=`printf "${NAME}=\\${TYPE}\n"`

eval `printf $VARS`