roy > naoya > 基礎プログラミングII > (7)CGI[1]

(7) CGI[1]

[1]CGIとは

インターネット上の掲示板では、入力エリアにデータを入力し「OK」を押すことでWebページに入力した情報が表示される。このようにHTML文書内にデータ入力エリアを配置し、入力後にボタンを押すとあらかじめ定められた処理を行い、結果が表示されるような仕掛けがある。このような仕組みをCGI(Common Gateway Interface)という。

CGIのデータ入力窓の集合を入力フォームという。 以下の入力フォームに値を入力、あるいは選択し「OK」ボタンを押してみよう。

氏名:
身長: cm  体重: kg

上のフォームで入力もしくは選択された値はCGI変数という特別な変数で、入力結果を処理するプログラムであるCGIスクリプトに送られる。このCGIスクリプトは一般にRubyもしくはPerlという言語で書かれており、何らかの処理を行った結果を、HTML文書として出力する。これを概念的に示すと以下のようになる。

氏名:[公益太郎]
身長:[1][7][0]cm
体重:[0][6][5]kg
[OK][reset]

Ruby(Perl)プログラムが値を受け取り、何らかの処理を実行すると同時に、結果出力用のHTML文書を生成する。

<html>
<head>
<title>結果!</head>
</head>
<body>
<p>うんたら</p>
</body>
</html>

[2]CGIの作り方

CGIは以下の3つのファイルにより構成される。

CGIを構成する3つのファイル

  1. Webサーバーに対して「ここでCGIプログラムを利用する」という宣言を記述したファイル
  2. 利用者がデータを入力するためのHTML文書
  3. 入力したデータを受け取って処理をするプログラム

[3]CGIプログラムの利用宣言

CGIを構成するファイルのうち「入力したデータを受け取って処理をするプログラム」がRubyのプログラムに相当する。

Rubyプログラムは自分で作成したruby/などのディレクトリに保存していたが、Web上でプログラムを実行させるためには、public_htmlの中にプログラムのファイルを置く。htmlファイルと同様に、ブラウザから閲覧させたいファイルは全てpublic_htmlのディレクトリ内に置いておかなければならない。

ここでは、CGIを利用するためのディレクトリをpublic_htmlの中に新たに作成し、CGI関連のファイルは全てその中に保存しておくことにする。

仮に、作成するディレクトリがcgi-binである場合、まず

sime{c1xxxxx}% cd public_html[Return]
sime{c1xxxxx}% mkdir cgi-bin[Return]

というように入力する。mkdirコマンドはディレクトリ作成コマンドであり、cgi-binというディレクトリを作成している。

次に、「このディレクトリ内でCGIを利用する」という宣言を行う。具体的にはcgi-binのディレクトリ内に.htaccessという名前のファイルを作成する(先頭のドットを忘れない!)。

このファイルを作成するためには、emacsでFile:~/public_html/cgi-bin/.htaccess[Return]とすればよい。ファイルを新規作成したら、以下の内容を記述して保存する。

AddHandler cgi-script   .rb
Options  +ExecCGI
AddType "text/html; charset=utf-8" .html

これにより、以後このディレクトリに作成する.rbの拡張子を持つファイルは、全てCGIスクリプトと認識される。

CGIプログラムの利用宣言

  1. CGI関連ファイルはpublic_htmlの中に専用のディレクトリを作成し、その中に一括で置いておく(授業ではcgi-binとする)。
  2. ディレクトリを作成するためのコマンドはmkdir
  3. cgi-binの中に.htaccessという名称のファイルを置く(ファイル内の記載内容は上を参照)。

[4]データ入力用HTML文書の構成

HTML言語を使用したWebページの記述方法については、1年生の情報リテラシーIIで実施済みであるが、入力フォームの作成は多少複雑である。ここでは入力フォームの作り方について確認する。HTML自体に不安がある場合は情報リテラシーIIのページを確認しよう。

冒頭で示した入力フォームとそのソースを見てみよう(form.html)。

氏名:
身長: cm  体重: kg

<html>
<head><title>購入ページ</title></head>
<body>
<form method="POST" action="./bmi.rb">
<p class="item">氏名:
<input type="text" name="name" maxlength="40"><br>
身長:
<select name="height1">
  <option> 1</option>
  <option> 2</option>
 </select>
<select name="height2">
  <option> 0</option>
  <option> 1</option>
  <option> 2</option>
  <option> 3</option>
  <option> 4</option>
  <option> 5</option>
  <option> 6</option>
  <option> 7</option>
  <option> 8</option>
  <option> 9</option>
 </select>
<select name="height3">
  <option> 0</option>
  <option> 1</option>
  <option> 2</option>
  <option> 3</option>
  <option> 4</option>
  <option> 5</option>
  <option> 6</option>
  <option> 7</option>
  <option> 8</option>
  <option> 9</option>
 </select>cm  
 体重:<select name="weight1">
  <option> 0</option>
  <option> 1</option>
  <option> 2</option>
  <option> 3</option>
 </select>
<select name="weight2">
  <option> 0</option>
  <option> 1</option>
  <option> 2</option>
  <option> 3</option>
  <option> 4</option>
  <option> 5</option>
  <option> 6</option>
  <option> 7</option>
  <option> 8</option>
  <option> 9</option>
 </select>
<select name="weight3">
  <option> 0</option>
  <option> 1</option>
  <option> 2</option>
  <option> 3</option>
  <option> 4</option>
  <option> 5</option>
  <option> 6</option>
  <option> 7</option>
  <option> 8</option>
  <option> 9</option>
 </select>kg<br>

<input name="ok" type="submit" value="OK">
<input name="ng" type="reset" value="reset">
</p>
</form>
</body>
</html>

ソースを見ると、入力フォームは、form要素(<form>タグ)を使って書かれていることがわかる。form要素の基本構造は

<form method="メソッド" action="./スクリプト">


</form>

となる。メソッドの部分はGETまたはPOSTのどちらかを指定する。GETは最大で255文字までしか引き渡すことができない(今回は名前や数字があるが、これらを全て含めて255文字)。項目数が多い場合や長い文章を入力させる場合はPOSTを指定する。ここではPOSTを使うものとして説明を続ける。

スクリプトの部分は入力データの引渡し先である。このソースを見ると、./bmi.rbとなっており(./は同一ディレクトリをあらわすので)、cgi-binディレクトリの中にあるbmi.rbがデータを受け取って処理をしていることがわかる。

このformの例では、

  • nameという名前の最大40文字の文字列
  • height1という名前で1、2のいずれか
  • height2という名前で0~9のいずれか
  • height3という名前で0~9のいずれか
  • weight1という名前で0、1、2、3のいずれか
  • weight2という名前で0~9のいずれか
  • weight3という名前で0~9のいずれか

をそれぞれ受け取り、bmi.rbに引き渡していることがわかる。入力フォームに用いる部品の詳細については次週とりあげる。

データ入力用のHTML文書

  • 入力フォームはform要素で記述する。form要素にはmethod属性とaction属性を指定する。
  • 1行のテキスト入力フィールドはinput要素を用いる。
  • プルダウンメニューはselect要素を用い、メニュー項目はoption要素を用いて記述する。

[5]CGIスクリプト(Rubyプログラム)の構成

CGIスクリプトとなるRubyプログラムでは、冒頭で必ず以下を記述する。

#!/usr/bin/env ruby
# coding: utf-8

require 'cgi'
c = CGI.new(:accept_charset => "UTF-8")
print "Content-type: text/html; charset=UTF-8\n\n"

1行目は必ず記述するおまじないであるが、CGIスクリプトを書く場合は通常とは異なるので注意しよう。

c = CGI.new(:accept_charset => "UTF-8")で、HTMLの入力フォームから引き渡された値が、ハッシュ変数cに代入される。「:accept_charset => "UTF-8"」の部分は、入力フォームから引き渡された値の文字コードをUTF-8にせよという指示。なお、変数cはどんな名前にしても構わない。

cにはハッシュ値として代入されるので、各入力値は、HTMLが引き渡す際に設定したnameやheight1をkeyとするvalueという形で取り出すことができる。

例えば

var1 = c["height1"]

とすれば、keyのheight1に対応するvalueがvar1に代入される。

以下は、上記の入力フォームに入力後、HTMLが引き渡すRubyプログラム(bmi.rb)である。

注意

  • このRubyプログラムは、~/public_html/cgi-bin/の中に保存すること。
  • 保存後に、このページにアクセスした人が誰でもCGIスクリプトを実行できるようにするため、ktermで以下を入力してファイルに実行属性を与える。
  • sime{c10xxxx]% chmod 755 bmi.rb[Return]もしくは
  • sime{c10xxxx]% chmod +x bmi.rb[Return]
#!/usr/bin/env ruby
# coding: utf-8

require 'cgi'
c = CGI.new(:accept_charset => "UTF-8")
print "Content-type: text/html; charset=UTF-8\n\n"

name = c["name"]
var1 = c["height1"]
var2 = c["height2"]
var3 = c["height3"]
var4 = c["weight1"]
var5 = c["weight2"]
var6 = c["weight3"]

height = (100 * var1.to_f + 10 * var2.to_f + var3.to_f) / 100
weight = (100 * var4.to_f + 10 * var5.to_f + var6.to_f)

bmi = weight / (height ** 2)


print"<html>
<head><title>BMI値</title></head>
<body>\n"

print"<h1>#{name}さんのBMI値</h1>\n"

print"<p>身長:#{height}m</p>\n"
print"<p>体重:#{weight}kg</p>\n"
printf("<p>BMI:%3.1f (理想は女性:21.5、男性:22)</p>\n",bmi)
printf("<p>理想体重は%4.1fkgです(男性の場合)。</p>\n",height ** 2 * 22)
printf("<p>理想体重は%4.1fkgです(女性の場合)。</p>\n",height ** 2 * 21.5)
print"</body>\n"
print"</html>\n"

このプログラムの上部では、HTMLより送られた値をnamevar1var2var3var4var5var6に代入し、heightweightbmiを計算している。

下部では、結果をHTML形式で出力するために<html>や<body>、<p>などのタグをprintやprintfを使って記述している。プログラムの下部には#{・・・}という記法があるが、{}内には計算式や変数を指定することができる。例えば、

print"10+20は#{10+20}です\n"

とすると{}内の10+20の計算が行なわれ、

10+20は30です

と表示される。また、

x=30
print"10+20は#{x}です\n"

とすると、xに代入された値である30が入れ込まれ、

10+20は30です

と表示される。これらは、いずれもprintfで書き直すことができる。すなわち、

x=30
print"10+20は#{x}です\n"

x=30
printf("10+20は%dです\n",x)

の出力結果は同一となる。

[6]CGIのまとめ

CGIを作成するためには幾つかのルールがあった。この点についてまとめよう。

  1. public_htmlの中にcgi専用のディレクトリ(例えばcgi-bin)を作る。以下で作成する3つのファイルはいずれもこのディレクトリに保存する。
  2. このディレクトリでcgiを利用するという宣言を記述した.htaccessを作成する。
  3. ユーザがデータを入力するためのHTML文書(xxx.html)を作成する。
  4. 入力したデータを受け取って処理をして結果出力用のHTML文書を生成するCGIスクリプト(xxx.rb)を作成する。
  5. Rubyで書かれたCGIスクリプトを自分以外の人でも実行できるように、アクセス権を与える。

CGI専用ディレクトリの作成

CGIを利用するためのディレクトリcgi-binをpublic_htmlの中に新たに作成する。このためにpublic_htmlディレクトリにcdコマンドで移動してから、ディレクトリ新規作成コマンドのmkdirを使用する。

sime{c1xxxxx}% cd public_html[Return]
sime{c1xxxxx}%  mkdir cgi-bin[Return]

.htaccessの作成

.htaccessの記述内容は以下の通り。emacsで作成する際に、File:~/public_html/cgi-bin/.htaccessとする。以下の2行を記述して保存する。

AddHandler cgi-script   .rb
Options  +ExecCGI
AddType "text/html; charset=utf-8" .html

入力フォームのHTMLファイルの作成

emacsで~/public_html/cgi-bin/の中にform.htmlを新規作成し、以下をコピーして貼り付け保存(字が小さいが上で示したものと同じ)。

<html>
<head><title>購入ページ</title></head>
<body>
<form method="POST" action="./bmi.rb">
<p class="item">氏名:
<input type="text" name="name" maxlength="40"><br>
身長:
<select name="height1">
  <option> 1</option>
  <option> 2</option>
 </select>
<select name="height2">
  <option> 0</option>
  <option> 1</option>
  <option> 2</option>
  <option> 3</option>
  <option> 4</option>
  <option> 5</option>
  <option> 6</option>
  <option> 7</option>
  <option> 8</option>
  <option> 9</option>
 </select>
<select name="height3">
  <option> 0</option>
  <option> 1</option>
  <option> 2</option>
  <option> 3</option>
  <option> 4</option>
  <option> 5</option>
  <option> 6</option>
  <option> 7</option>
  <option> 8</option>
  <option> 9</option>
 </select>cm  
 体重:<select name="weight1">
  <option> 0</option>
  <option> 1</option>
  <option> 2</option>
  <option> 3</option>
 </select>
<select name="weight2">
  <option> 0</option>
  <option> 1</option>
  <option> 2</option>
  <option> 3</option>
  <option> 4</option>
  <option> 5</option>
  <option> 6</option>
  <option> 7</option>
  <option> 8</option>
  <option> 9</option>
 </select>
<select name="weight3">
  <option> 0</option>
  <option> 1</option>
  <option> 2</option>
  <option> 3</option>
  <option> 4</option>
  <option> 5</option>
  <option> 6</option>
  <option> 7</option>
  <option> 8</option>
  <option> 9</option>
 </select>kg<br>

<input name="ok" type="submit" value="OK">
<input name="ng" type="reset" value="reset">
</p>
</form>
</body>
</html>

CGIスクリプト(Rubyプログラム)の作成

以下はCGIスクリプトの例である。bmi.rbという名前をつけて保存する。cgi-binの中に保存するため、emacsで新規作成する場合、File:~/public_html/cgi-bin/kakaku.rbとする(字が小さいが上で示したものと同じ)。

#!/usr/bin/env ruby
# coding: utf-8

require 'cgi'
c = CGI.new(:accept_charset => "UTF-8")
print "Content-type: text/html; charset=UTF-8\n\n"

name = c["name"]
var1 = c["height1"]
var2 = c["height2"]
var3 = c["height3"]
var4 = c["weight1"]
var5 = c["weight2"]
var6 = c["weight3"]

height = (100 * var1.to_f + 10 * var2.to_f + var3.to_f) / 100
weight = (100 * var4.to_f + 10 * var5.to_f + var6.to_f)

bmi = weight / (height ** 2)


print"<html>
<head><title>BMI値</title></head>
<body>\n"

print"<h1>#{name}さんのBMI値</h1>\n"

print"<p>身長:#{height}m</p>\n"
print"<p>体重:#{weight}kg</p>\n"
printf("<p>BMI:%3.1f (理想は女性:21.5、男性:22)</p>\n",bmi)
printf("<p>理想体重は%4.1fkgです(男性の場合)。</p>\n",height ** 2 * 22)
printf("<p>理想体重は%4.1fkgです(女性の場合)。</p>\n",height ** 2 * 21.5)
print"</body>\n"
print"</html>\n"

CGIスクリプト(Rubyプログラム)への実行属性の付与

保存後には、CGIスクリプトとして実行できるようにするため、ktermで以下を入力する。
sime{c10xxxx]% chmod 755 bmi.rb[Return]もしくは
sime{c10xxxx]% chmod +x bmi.rb[Return]

これら全ての手順を抜け落ちなく実施すると

http://roy.e.koeki-u.ac.jp/~c1xxxxx/cgi-bin/form.html

で入力フォームが表示され、適宜入力してOKを押すと何らかの結果が出るはずである。

[7]CGI実行時のエラーメッセージ

表示されるエラーメッセージの内容によって、エラー内容を概ね特定することができる。

ブラウザに入力フォームのURLを入力するとNot Foundと表示される。

  1. URLが間違っている。URLはhttp://roy.e.koeki-u.ac.jp/~c10xxxx/cgi-bin/yyyy.htmlとなる。xxxxは自分の学籍番号(チェックディジットなし)、yyyは作成した入力フォームのファイル名となる。
  2. form.htmlの保存場所が間違っている。ktermでcgi-binのディレクトリに移動し、lsを入力して作成したファイルがあるかどうか確認する。違う場所に保存した場合は、ktermでmvコマンドを使用して移動する。mvコマンドについては、UNIX主要コマンドのページを参照のこと。

入力フォームに入力しOKを押すとPermission Deniedと表示される。

  1. .htaccessファイルを作成していないか、作成したが保存できていないか、保存した場所が違う。
  2. CGIスクリプト(Rubyプログラム)に実行属性を付与していない。

入力フォームに入力しOKを押すとInternal Server Errorと表示される。

CGIスクリプト(Rubyプログラム)の書き間違え。具体的には、変数名の入力間違いの可能性が高い。

入力フォームに入力しOKを押すと真っ白な画面になる。

CGIスクリプト(Rubyプログラム)の書き間違え。具体的には、変数名の入力間違いの可能性が高い。

[8]CGI用プログラムのエラー検出

CGI実行時にエラーが出ても、Internal Server Errorの表示や真っ白な画面が表示されるだけで、どこが間違っているのかを確認することができない。エラーがどこにあるのかを確認するためには、ktermでプログラムを実施してみると良い。

プログラムの保存場所がいつも(~/program)とは異なることに注意し、~/public_html/cgi-binに移動してから実行してみよう。

実行した直後にエラーが表示されれば、これまで作成してきたプログラムと同様に表示されたエラーメッセージを参考にして修正すればよい。特にエラーが出ない場合、kterm上でプログラムを実行してみよう。

この場合、Webページからデータを引き渡すことができないので、name属性=値[Return]の形式で必要なデータを入力する。全てのデータを入力したらCtrl+dを入力すると、入力フォームでデータを入力したものとして、これらの値がプログラムに引き渡される。

sime{c1xxxxx}% ./bmi.rb[Return] 
(offline mode: enter name=value pairs on standard input)
name="Koeki Taro"[Return]
height1=1[Return]
height2=5[Return]
height3=0[Return] 左辺右辺と=の間にはスペースをあけない
weight1=0[Return] ○ weight1=0
weight2=9[Return] × weight2 = 9
weight3=0[Return]
[Ctrl+d]
<html>   入力フォームからデータが引き渡されたものとして実行結果が表示される
<head><title>BMI値</title></head>
<body>
<h1>Koeki TaroさんのBMI値</h1>
    :

プログラムにエラーがあれば、通常のプログラムと同様にエラーメッセージが表示される。必要な修正を行い、繰り返し実行しながらエラーを除去しよう。

[9]作業

実際にCGIを設置して動作を確認する。

[10]入力フォームの構成部品について

入力フォームを作成する場合、まずform要素を使用する。<form></form>の間にラジオボタンや入力フィールドを配置し、<form>内に指定した方法でCGIスクリプトに引き渡す。

form要素については既に説明済みであるが、念のため再掲する。

<form method="メソッド" action="./スクリプト">


</form>

となる。メソッドの部分はGETまたはPOSTのどちらかを指定する。GETは最大で255文字までしか送ることができない。項目数が多い場合や長い文章を入力させる場合はPOSTを指定する。ここではPOSTを使うものとして説明を続ける。

スクリプトの部分は入力データの引渡し先である。このソースを見ると、./kakaku.rbとなっており(./は同一ディレクトリをあらわすので)、cgi-binディレクトリの中にあるkakaku.rbがデータを受け取って処理をしていることがわかる。

<form></form>の間に配置するフォームの構成部品について、まずは外観を示し、その後説明を加える。

1行のテキスト入力フィールド:
チェックボックス(複数選択可):
ラジオボタン(ひとつのみ選択可):

プルダウンメニュー:
送信ボタン:
リセットボタン:

これらの構成部品はinput要素、textarea要素、select要素を用いて作成することができる。textarea要素は複数行のテキスト入力フィールドの作成に用い、select要素はプルダウンメニューの作成に用いる。それ以外の部品は全てinput要素で作成し、type属性で区別する。

部品名

要素名

type属性

1行のテキスト入力フィールド

input

text

チェックボックス

input

checkbox

ラジオボタン

input

radio

複数行のテキスト入力フィールド

textarea

不要

プルダウンメニュー

select

不要(選択肢はoption属性を使用)

送信ボタン

input

submit

リセットボタン

input

reset

[11]1行のテキスト入力フィールド

input要素を利用し、type属性としてtextを指定する。

<input type="text" name="namae" size="40" maxlength="40">

  • <input>に対する</input>は不要。
  • name属性はCGIスクリプトに引き渡す際のkeyとして使用するため、必ず指定しなければならない。入力した値がkey(ここではnamae)に対応するvalueとなる。
  • size属性は左右の幅であり文字数で指定する。
  • maxlength属性は入力できる最大文字数であり、これも文字数で指定する。
  • size属性とmaxlength属性はなくても良い。

maxlength属性を5とすると入力できる文字数が最大5文字となる。

size属性を5とすると入力フィールドの幅が狭くなる。

[12]チェックボックス(複数選択可)

input要素を利用し、type属性としてcheckboxを指定する。

<input type="checkbox" name="cbx" value="1">チキンカレー

チキンカレー

  • <input>に対する</input>は不要。
  • name属性はCGIスクリプトに引き渡す際のkey、value属性はvalueとして使用するため、必ず指定しなければならない。
  • 通常は、チェックボックスは単独では使用せず、複数の項目から該当するものを全て選択するような場合に用いることが多い。このため、複数のチェックボックスのname属性は全て異なる名称にする。チェックをつけた項目のvalueがプログラムに引き渡される(チェックされていない項目のvalueをプログラム内で取り出すとnilになる)。
  • checked属性を追加し、checked="checked"と書くことで、その項目を最初から選ばれた状態にすることができる。

3つ目のチェックボックスのみchecked="checked"を追加

チキンカレー
シーフードカレー
野菜カレー

[13]ラジオボタン(ひとつのみ選択可能)

input要素を利用し、type属性としてradioを指定する。

<input type="radio" name="rd" value="20代">20代

20代

  • <input>に対する</input>は不要。
  • name属性はCGIスクリプトに引き渡す際のkey、value属性はvalueとして使用するため、必ず指定しなければならない。
  • ラジオボタンは単独では使用せず、複数の項目から1つを選択する際に用いることが多い。name属性は全て同一にする。
  • name属性を同一にしない場合、複数項目が選択できてしまう。
  • checked属性を追加し、checked="checked"と書くことで、その項目を最初から選ばれた状態にすることができる。

3つ目のチェックボックスのみchecked="checked"を追加

20代
30代
40代

左側はname属性をいずれもageとした場合(1つしか選択できない)。右側はname属性を順番にage1、age2、age3とした場合(3つとも選択できてしまう)。

20代
30代
40代

20代
30代
40代


[14]複数行のテキスト入力フィールド

textarea要素を利用する。type属性は不要。

<textarea rows="3" cols="30" name="youbou"></textarea>

  • <textarea>に対する</textarea>が必要。
  • name属性はCGIスクリプトに引き渡す際のkeyとして使用するため、必ず指定しなければならない。入力した値がkeyに対応するvalueとなる。
  • rows属性で行数、cols属性では幅を1行当たりの文字数で指定する。
  • <textarea></textarea>間にテキストを挿入すると、フィールド内にその文字が表示される。

rowsを2、colsを10にした場合

<textarea></textarea>間に「感想をお願いします」と入れた場合

[15]プルダウンメニュー

select要素を利用する。各選択肢にはoption要素を利用する。type属性は不要。

<select name="age">
<option>10代</option>
<option>20代</option>
<option>30代</option>
<option>40代</option>
<option>50代</option>
</select>

  • <select>に対する</select>が必要。
  • <select></select>間にoption要素を用いて選択肢を記述する。
  • name属性はCGIスクリプトに引き渡す際のkeyとして使用するため、必ず指定しなければならない。opetion要素の中でユーザが実際に選択した値がkeyに対応するvalueとなる。
  • select要素に対してsize属性で行数を指定すると、プルダウンメニューではなく、リストボックスとして表示される。

select要素にsize属性で、size="3"と指定した場合

[16]送信ボタン

input要素を利用し、type属性としてsubmitを指定する。

<input name="ok" type="submit" value="OK">

  • <input>に対する</input>は不要。
  • value属性はボタンに表示する名称となる。
  • name属性は送信ボタンが単独の場合は不要。送信ボタンが複数ある場合、これがCGIスクリプトに引き渡す際のkeyとなる(単独の場合はこのボタンを押すとCGIスクリプトにデータが引き渡されるのみであるが、複数の送信ボタンがある場合は、データをCGIスクリプトに引き渡すことに加え、どの送信ボタンを押したかという情報が伝達される)。

value属性を「送信する」にした場合

[17]リセットボタン

input要素を利用し、type属性としてresetを指定する。

<input name="ng" type="reset" value="reset">

  • <input>に対する</input>は不要。
  • value属性はボタンに表示する名称となる。
  • このボタンを押すと、form要素内に記述した(選択した)値がリセットされる。
  • name属性は実質的には不要(つけても良いが意味がない)。

value属性を「やっぱりやめる」にした場合

[18]CGIスクリプトの応用(処理の切替)

先週は入力した値に基づいて計算を行い、結果を表示するCGIスクリプトについて見てきた。今週は一歩進んで、入力した値により出力を切り替える例を作成してみよう。つまりif文を用いて結果を切り替える。

氏名:
性別: 男性 女性 どちらでもない
以下の各項目について当てはまるものに全てチェックをつけてください。
いろいろ勉強して自分を深めたい
社会に出て成功したいと思う
いつも何か目標を持っている
手がけたことは最善を尽くしたい

今回はラジオボタン(これ→)やチェックボックス(これ→)が追加されている。上述の通りこれらのパーツはいずれもいずれもinput要素で作成できる。パーツの使い分けはtype属性で指定している。

  • type="text":1行の入力フィールド
  • type="radio":ラジオボタン
  • type="checkbox":チェックボックス
  • type="submit":送信ボタン
  • type="reset":リセットボタン

この入力フォームは実際には以下のように書かれている(入力フォームの部分のみ)。

<html>
<head><title>購入ページ</title></head>
<body>

<form method="POST" action="./shinri.rb">
<p class="item">氏名:
<input type="text" name="name" maxlength="40"><br>
性別:
<input type="radio" name="rd" value="男性">男性
<input type="radio" name="rd" value="女性">女性
<input type="radio" name="rd" value="不明">どちらでもない<br>
以下の各項目について当てはまるものに全てチェックをつけてください。<br>
<input type="checkbox" name="box1" value="1">
いろいろ勉強して自分を深めたい<br>
<input type="checkbox" name="box2" value="1">
社会に出て成功したいと思う<br>
<input type="checkbox" name="box3" value="1">
いつも何か目標を持っている<br>
<input type="checkbox" name="box4" value="1">
手がけたことは最善を尽くしたい<br>

<input type="submit" name="ok" value="OK">
<input type="reset" name="ng" value="reset">
</p>
</form>
</body>
</html>

shinri.htmlのform要素のaction属性を見ると、入力データをshinri.rbに引き渡していることが分かる。shinri.rbは入力データを受け取り、処理をして結果のHTML文書を出力するCGIスクリプトである。前回のkakaku.rbと同じく、変数cのハッシュ値として入力値を取り出しているが、if文が追加されているため若干構造が複雑になっている。このプログラムではチェックをした項目数に応じてif文でメッセージを変化させている。

#!/usr/bin/env ruby
# coding: utf-8

require 'cgi'
c = CGI.new(:accept_charset => "UTF-8")
print "Content-type: text/html; charset=UTF-8\n\n"

namae = c["name"]
seibetsu = c["rd"]
q1 = c["box1"]
q2 = c["box2"]
q3 = c["box3"]
q4 = c["box4"]

point = q1.to_i + q2.to_i + q3.to_i + q4.to_i

print "<html>
<head><title>診断結果</title></head>
<body>\n"

print "<h1>#{namae}さん(#{seibetsu})の診断結果</h1>\n"

print "<p>あなたがチェックをした項目数は#{point}個です。</p>\n"

print "<p>"
if point == 4
  print "やる気満々ですね。このまま頑張って!\n"
elsif point == 3
  print "結構頑張り屋さんですねえ。この調子で。\n"
elsif point == 2
  print "うーん。まあまあですかねえ\n"
elsif point == 1
  print "うーん。うーん。もうちょっとやる気見せましょう。\n"
else
  print "やる気ないですね。\n"
end
print "</p>\n"
print "</body>\n"
print "</html>\n"

[19]作業

shinri.htmlでは4つのチェックボックスが設置されており、チェックした数に応じて異なるメッセージが表示されるようCGIスクリプトが書かれている。チェックボックスをあと2つ追加し(=htmlファイルを作成して内容を書き換え)、チェックした項目数に応じて異なるメッセージが表示されるように変更してみよう(=shinri.rbを改良する)。

[20]レポート課題

問題(10点満点):CGIを使い、Web上で動くプログラムを作成する。ifを使用していることを要件とする。10点満点だが、単に授業用のページ(他の先生も含む)に掲載されているものを複写し、多少言葉を変えただけの場合はプログラム点の配点を最低点とする。ifを使うとなると、例えば以下のようなテーマが考えられる。

  • 2年春学期までに修得した単位数を入力すると、単位数に応じたメッセージが出る。
  • 4択クイズ。
  • 走行距離と消費したガソリンの量を入力すると、燃費が計算され、値に応じてメッセージが出る。

4択クイズの場合、以下のように、正解のvalueのみ1、不正解は0とすればよい。

Q1 1+1=?

<p><input type="radio" name="q1" value="0">0

<input type="radio" name="q1" value="0">1

<input type="radio" name="q1" value="1">2

<input type="radio" name="q1" value="0">3</p>


  • 提出先:課題提出用メールアドレス
  • 提出期限:第1提出期限、第2提出期限を設定
  • メールのSubject:課題6
  • 本文の構成:1行目で学籍番号、氏名を記載する。2行目以降は下記の構成とする
  1. データを入力するWebページのURL
  2. 作成したプログラム(CGIスクリプト)
  3. プログラムの説明
  4. 感想

  • 採点基準:期限内提出点(2点)、メールの体裁(1点)、プログラム(1~5点)、説明(2点)
  • プログラムの説明:何をするCGIなのか、Webページの入力フォームから受け取った値をどのように処理しているのかについて
  • わかりにくい説明や、Webページを単にコピー&ペーストしただけの説明は減点することがある。一度読み直してから提出すること。
  • 驚異的に良くできているレポートについては満点を超える得点をつけることがある。
  • よくできていたレポートは、他の人の参考になるよう、本人が特定できないような形で掲載する。掲載してほしくない場合はメールでの課題提出時にその旨記載すること。

Tips:emacsでの日本語入力のオンオフはCtrl-oです

Tips:ktermでのプログラムの実行結果をメールに貼り付けるには、コピーしたい箇所をマウスで選択し、emacs(Mew)上でマウスの真ん中ボタンをクリックする

Tips:Mewによるメールの送り方はMewコマンドを参照