CGIに対して、たとえば掲示板なら投稿文,氏名などの情報を引渡すでしょう。
また、検索機能を持つCGIなら、検索対象となるキーワードを情報として渡すことになるでしょう。
ウェブでは、このようなデータ(クエリといいます)について、以下のような形式で渡します。
クエリ名=クエリ値クエリ名とは、データの種類を判別するためにCGI側が付けている名前で、クエリ値は実際に引渡す文字列です。
たとえば、氏名の入力について、CGI側が「name」というクエリ名を与えたところ、ウェブブラウザから「NAKAMURA」というクエリ値が送られてきた場合は、CGIには以下のようなクエリが引渡されます。
name=NAKAMURAところが、日本語の文字列「中村」を引渡そうとすると、以下のように訳の分からない文字列が引渡されます(シフトJISコードの場合)。
name=%92%86%91%BA実は、クエリ値において、使ってはいけない文字や文字コードが決められていて、日本語文字は大半が使ってはいけない文字コードとなっているのです。
そこで、こういった文字は、一バイトづつ「%XX」という形に自動的に変換されるという訳です。
CGI側は、送られてきたデータを決まりに従って復元することになります。
<a>要素のhref属性値及び<form>要素のaction属性値にクエリを持ったURLを記述する場合、最低でもクエリ内の「/」だけはURLエンコードしておかないといけません。
クエリ内は「/」以外の文字も半角英数字以外は全てURLエンコードしなければならないことになっておりますが、特に「/」がクエリに入っていると相対URLの解釈が不正になる事があります。
具体例として、下位ディレクトリ内のCGIスクリプトにクエリを付けた例を挙げておきます。
<a href="cgi/test.cgi?a=dir/subdir/file.html">URLエンコーディングに関する情報</a>というクエリをつけたリンクを選択した場合、そのページの相対アドレスの基準となるディレクトリが、
cgi/test.cgi?a=dir/subdir/
と誤認される可能性があります。
実は誤認されるかどうかはユーザエージェントが相対パスを解析するアルゴリズムに依存します。
具体的には「?」で始まるクエリを先に切捨てるか、その前にURLに含まれる「/」を見てパスの構造を解析するかによって判定結果が異なると言う事です。
前者ならクエリを先に切落すので、実アドレスは「cgi/test.cgi」と正しく判定され、相対パスのディレクトリがおかしくなる事はありません。
しかし、後者だと「/」を基準に判定した結果「cgi/test.cgi?a=dir/subdir/file.html」が本体と判断されて誤認に繋がります。
<a href="cgi/test.cgi?a=dir%2fsubdir%2ffile.html">URLエンコーディングに関する情報</a>とクエリの「/」を「%2f」にエンコードしておいたリンクなら、そのページの相対アドレスの基準となるディレクトリは正しく
cgi/
と判断されるでしょう。
尚、<input>要素, <textarea>要素などによるクエリの引渡しではブラウザによって自動的にURLエンコードが行われますので、この様な対策は不要です。
クエリが複数ある場合、区切り記号で区切られます。
例えば、区切り記号を「;」として、三つのクエリを記述する場合は、以下のようになります。
name1=value1;name2=value2;name3=value3区切り記号は多くの場合「&」が用いられますが、これは本当は好ましくはありません。
なぜなら、HTMLタグの属性値に書かれた場合、実体参照と紛らわしいからです。
&」を使いたい場合は「&」と書かなければ思わぬ誤作動の原因となり兼ねません。&」を区切り記号として採用していることから、ほとんどのウェブブラウザが「&」を区切り記号に用いております。HTMLの規格としては、区切り記号には「;」を用いるのが望ましいとされております。
CGIを作る場合はこちらを採用するようにしましょう。
但し、多くのウェブブラウザは「&」を区切り記号として用いているので、どちらでも問題なく動作するようにすれば良いのです。
さて、クエリの列をどうやってCGIに引渡すのでしょう。
この方法には二通りのメソッドが用意されております。
GETメソッドは、URLの後ろにクエリを「?」に続いて書くことでデータを引渡すやり方です。
GETメソッドでデータを引渡すにはフォーム(<form>要素)を用いる方法だけでなく、固定されたデータならhref属性値にクエリを付けたURLを与えた<a>要素でも引渡しができます。
受取る側は、URLの後ろのクエリ列を切出すことで受取れますが、実際にはクエリ列だけの部分が引渡されるため切出す手続きもせずに受取れます。
GETメソッドは非常に簡単にデータの引渡しができるのが利点ですが、欠点としてあまり長いクエリ列は引渡せない事と、URLの後ろに直接記述されるのでクエリの内容が大っぴらに公開されてしまう事が欠点です。
POSTメソッドは、パスとは別にデータを送る方法です。
POSTメソッドでデータを引渡すには必ずフォーム(<form>要素)を用いなければなりません。
受取る側も特別な方法で入力しなければなりません。
その代わり、大量のデータが引渡せることと、URLにクエリが反映されないという長所があります。