ここからはCGIという仕組みを利用した注文書を作ります。
CGIというのはCommon Gateway Interface(コモン・ゲートウェイ・インタフェース)のことで、ブラウザからサーバにあるプログラムを呼び出して動かす仕組みです。
HTMLからフォームやリンクのURI(Uniform Resource Identifier)によってCGIのプログラムを呼び出したり、プログラムにデータを送信します。
CGIのプログラムはサーバ上で動作し、また、受信したデータや加工したデータをサーバ内に記録することができます。また、記録したデータを読み込んで、HTMLファイルに加工することでブラウザの画面に結果を表示します。
このような仕組みは多くの通販サイトで利用されています。
注文者が商品を選び、注文のデータと一緒に送り先である個人情報を送ります。するとサーバには、商品の購入履歴や会員情報として顧客データが記録されます。
利用者としては、次に注文をする際には、サーバに預けたデータを再利用することもできます。会員制のサイトで、自分のデータが表示されるのはこのような仕組みだからです。
ショップ側にも大きなメリットがあります。利用者から送られたデータをそのままコンピュータで処理できるので、名簿や注文書を作り直す必要がありません。また、全顧客のデータを分析することで集計や統計にも利用できます。
CGIは、サーバで動くデータの記録システム全般を指し示す言葉で、実際にはperl(パール)やPHP(ピーエイチピー)というプログラム言語を使ってCGIファイルを記述します。
では、JavaScriptとはどう違うのでしょうか。どちらもスクリプト言語と呼ばれますが、次のように違いがあります。
JavaScript | CGIプログラム | |
---|---|---|
記述場所 | HTMLファイル内 JSファイル内 |
CGIファイル内 |
動作場所 | ブラウザ | サーバ |
記述方法 | テキスト | テキスト |
大きな違いは、動作する場所です。JavaScriptで書かれたプログラムはブラウザが計算や処理を行いますが、CGIではサーバが計算と処理を行います。
記述は、テキストファイルを使いますので、どちらもメモ帳やエディタで編集が可能です。
CGIファイルは、一般的に拡張子を「.cgi」とします。(PHPの場合は、.phpとなっています。)
このようなCGIファイルはネット上にも有料・無料で配布されています。それらを調節して自らサーバに設置して利用します。
実例:order.cgi(注文の管理プログラム)
まずは、これから利用するCGIプログラムの実例を見てみましょう。
上記の実例をクリックすると受注処理という画面が表示されます。これは不用意に誰もがCGIプログラムを利用されては困るため、パスワードを入力しないと入れない仕組みになっています。
管理者パスワードに「0000」と入力してログインボタンを押すと管理画面が現れます。
この管理画面では、送られてきた注文書を一覧で表示します。
次に、修正のリンクを押すと、個別の注文書画面が開きます。
個別画面では、Status(ステータス)の変更と、データの変更が可能です。備考欄には、ショップ側がメモ書きを残せます。ステータスには「表示」「非表示」「削除」があり、表示と非表示は一覧表示の変更、削除はデータをログファイルから消してしまいます。更新ボタンを押すと、変更が適用されて一覧画面に戻ります。
ここで表示されている注文書のデータはフォームから送られてきたものです。
試しにフォームから注文をしてみましょう。
実例:p8.html(注文フォーム)
注文ができたら、また管理プログラムを見てください。注文が1つ増えているはずです。
ただし、2回以上の注文ができないようになっています。これはいたずら発注を防ぐためでもありますが、CGIは誰でもサーバにデータを残せる仕組みなので、このレッスン用CGIの保護のためでもあります。
管理画面を見ると、この保護のために発注者のホスト情報を記録しています。(個別画面で表示されます)
いたずら防止のため記録をしないようにすることもできますので、注文を受け付けないように設定変更している場合もあります。
今回はCGIファイルは作成しません。
HTMLによるフォームの作り方と、CGIの仕組みを理解するに留めます。
今回はHTMLファイルで作ったフォームから、CGIファイルへデータを送信し、CGIファイルがデータをログ(履歴)として保存します。また、そのログの管理も1つのCGIファイルで行います。
また、CGIの処理をサーバに記録する2つのログファイルを使います。1つは、注文書データの保存用で、もう1つは受注番号の管理用です。
今回使うCGIファイルは、レッスン用の簡易版です。CGIファイルは直接ダウンロードできないため、拡張子を変えたファイルを用意しました。
この「order.txt」のリンクをクリックしてテキストを表示させます。その内容をメモ帳にコピーします。ファイルの種類を「すべてのファイル」に変更し、文字エンコードを「UTF-8」にしてからファイル名を「order.cgi」にして保存してください。
ログファイルは「order.csv」という名前で、空のテキストファイルを作ります。注文が書き込まれると、CSV形式(カンマ区切りのテキスト)で記録されます。
カウンターファイルは「count.txt」という名前で、「0」と入力したテキストファイルを作ります。注文が書き込まれると1ずつ足されて記録されます。
これら3つのファイルは同じフォルダに入れて使います。今回はレッスンで作るフォームと同じフォルダに置きます。
HTMLのフォームはメール用に作ったp7.htmlを改良して作ります。
まずは「p7.html」をコピーして「p8.html」と名前を変更します。
実例(p8-1.html)
フォームをCGIに送信するための準備を行います。
テーブルについても、名前や住所などの個人情報を入力する欄を追加します。
<div id="mainmenu">
<div class="menutitle">注文フォーム</div>
<form name="order" action="order.cgi" method="post" onSubmit="return check_order2();">
<input type="hidden" name="mode" value="add">
<table border="2" cellspacing="2" cellpadding="2">
<form>タグの中にフォームの送信先としてaction属性で「order.cgi」を指定します。method属性はデータの送信方法で、「post」は大量のデータを送信するのに向いています。「get」にするとURLに送信するデータが表示され、セキュリティ上よくありません。
getの場合に懸念される問題は、例えばURLを自動的に作って発注を自動的に引き起こすことができるようになります。また、どのようなデータを送信しているか分析することで、サーバに不正な命令を送って侵入されるという危険性もあります。
onSubmitは「return false;」になっているところをユーザー関数に置き換えています。ユーザー関数からの戻り値を送信イベントに与えると言う意味になっています。
ユーザー関数check_order2()を使って、フォームの中身をチェックして、送信して良ければtrueが、送信できないときはfalseが戻ってきます。
まずは、テーブルに個人情報の項目を追加しましょう。それぞれの項目にname属性が付いているため、フォームの送信に利用されます。
<div class="menutitle">注文確認</div>
<textarea name="order_text" cols="90" rows="10" readonly id="order_text"></textarea>
<table border="0">
<tr>
<th>お名前</th>
<td><input name="name" type="text" id="name" size="50"></td>
</tr>
<tr>
<th>ご住所(1)</th>
<td><input name="add1" type="text" id="add1" size="50"></td>
</tr>
<tr>
<td align="center">ご住所(2)</td>
<td><input name="add2" type="text" id="add2" size="50"></td>
</tr>
<tr>
<th>電話番号</th>
<td><input name="tel" type="text" id="tel" size="50"></td>
</tr>
<tr>
<th>メールアドレス</th>
<td><input name="mail" type="text" id="mail" size="50"></td>
</tr>
<tr>
<td align="center">連絡事項</td>
<td><input name="sonota" type="text" id="sonota" size="50"></td>
</tr>
</table>
<div class="menutitle"><input type="submit" value="送信"></div>
</form>
「メール」のボタンもフォームの送信ボタンに変更します。
個人情報の項目については、CGIと連動していますので、項目を追加したり、順場を変更した場合にはCGIの初期設定に受け取る項目の名称を変更する必要があります。また、CGIで一覧表示するテーブルも項目に合わせて変更が必要です。
フォームとして送信される項目には、name属性が必要です。上部の注文書にある<input>タグにはname属性がありません。注文確認画面の<textarea>タグや上記で追加した<input>タグにはありますので、それらのみフォームのデータとして送信されることになるのです。
もし、注文書部分にもname属性があるとしたら、フォームをそれぞれ分割してしまえば、送信ボタンが含まれる<form>タグの範囲の中でフォームの送信が実行されます。
次の2つを比較してください。テーブル部分は省略して表記しています。
【1つのフォーム】
<div class="menutitle">注文フォーム</div> <form name="order" action="order.cgi" method="post" onSubmit="return check_order2();">
<input type="hidden" name="mode" value="add"> <注文書のテーブル> <div class="menutitle">注文確認</div>
<textarea name="order_text" cols="90" rows="10" readonly id="order_text"></textarea>
<個人情報のテーブル> <div class="menutitle"><input type="submit" value="送信"></div>
</form>
【2つのフォーム】
<div class="menutitle">注文フォーム</div> <form name="list">
<注文書のテーブル> </form> <div class="menutitle">注文確認</div>
<form name="order" action="order.cgi" method="post" onSubmit="return check_order2();">
<input type="hidden" name="mode" value="add"> <textarea name="order_text" cols="90" rows="10" readonly id="order_text"></textarea>
<個人情報のテーブル> <div class="menutitle"><input type="submit" value="送信"></div>
</form>
2つのフォームに分けた場合は、フォームの名前も別になるので、関連するスクリプトには名前の変更が必要です。
ユーザー関数を1つ追加しましょう。
フォームのタグ内にあったユーザー関数check_order2()です。送信ボタンを押すと実行され、未記入の項目がないか確認してから送信を実行します。
function check_order2() {
//入力必須項目の確認
bool = true;
if (document.order.order_text.value == "") bool = false;
if (document.order.name.value == "") bool = false;
if (document.order.add1.value == "") bool = false;
if (document.order.tel.value == "") bool = false;
if (document.order.mail.value == "") bool = false;
return bool;
}
注文確認画面、名前、住所(1)、電話番号、メールアドレスの各項目を調べて、空の項目があった時点で変数boolがtrueからfalseに変わります。
最後に変数boolをonSubmitに戻しているため、trueならフォームが送信され、falseならフォームが送信されません。
もし、このユーザー関数内にエラーがあるとフォームが送信されてしまうので注意が必要です。