前提:
サーバで動作するプログラミング言語(スクリプト系言語に限定)で書く。
ruby, python, JavaScript(nodeコマンド)はインストール済み
他に必要なもの(言語処理系など)があれば前章の(apacheを入れたのと同様の)方法で導入は可能
ファイルの拡張子は .rb
、.py
、.js
のように言語で標準的に使われているものにし (これは関連づけによる起動のためではなく、主目的は編集時などの便宜のため。起動プログラムについては後述する)
ファイル名は(アクセス時の文字コード上の混乱を避けるため)半角英数字にしておくことが望ましい。
サーバに接続してサーバ上のエディタで編集してもいいが (端末接続だとGUI的に使えないので不便が多いので)、 PCで編集してアップロードするといいだろう。
コンテンツに日本語を使うなら UTF-8
エンコーディングで保存すること。
以下の例は主にRubyで示す。
テキストを生成するだけのコード
#!/usr/bin/ruby
puts 'Content-type: text/plain' ; puts
puts '読めますか'
1行目はこのスクリプトを実行(起動)する言語インタプリタのフルパス名を指定するために必要な行(shebang などと呼ばれる)で、必ず行頭から、‘#!’ で始まる。
言語のプログラムの場所は以下のようなコマンドで確認できる。
which ruby # あるいは python node ...
HTTPヘッダーをまず出力する(ソース2行目)。最低限必要なのは Content-type ヘッダ。
まずはその MIME型(Content-typeヘッダの、値欄)として、text/plain としておく。
文字コードをここでついでに指定することもできる。その際は、値欄を
text/plain; charset=UTF-8
とする。
この情報については、HTML出力の場面では、HTMLの中に <meta http-equiv=...>
や <meta charset=...>
というメタタグを埋め込むという方法もよく使われている。
HTTPヘッダとHTTPボディ(本文)の間は空行で区切るのがHTTPの決まりごと。 上記ソースの、空のputs
が空行出力。
明示的に print "\n"
のようにしてもいい。
動作実験、と転送、と置き場所(転送先)
PC側で作成した場合、PC上でも上記のコードは実行できる。
サーバ上で編集するか、転送ソフト(sftp経由)でアップロードしてください。
サーバ上の $HOME/public_html/cgi-bin
が置き場所。なければ作成する (転送ソフトで作成してもいいがパーミッションにも注意すること)。
cd
cd public_html
mkdir cgi-bin
chmod 755 cgi-bin
このディレクトリにファイルを転送し、そのファイルも同様にパーミッションを 755 にする。(これは SuEXEC という Apacheの仕組みによる制約)
サーバ上でもコマンドとして起動可能。たとえば abc.rb というファイルだとすると、
cd
cd public_html/cgi-bin # ここまでは準備(カレントディレクトリの確定)
./abc.rb
のように起動できる。
転送モードに注意。SFTPやFTPでの転送は ‘binary’ と ‘text’ という2つのモードがある。
前者はファイルをそのまま加工なしで転送し、後者では改行文字などの調整をしつつ転送する。
Windowsでは改行文字が CR NL (\r
\n
)の2文字、Unixでは NL(\n
)1文字。
詳しくは転送ソフトの紹介サイトなどで確認されたい。なお、FileZillaでは .rb は デフォルトでは テキスト転送をしないようだ。
先頭行の行末に(Unixのテキストファイルとしては)余計な CR が入っていた場合(つまり転送モードがtextモードでなかった場合)、
サーバ上でコマンドとして実行した場合に、以下のようなエラーメッセージが出るだろう。
./abc.rb
=> (LoadError)y: No such file or directory --
HTMLを生成するコード
#!/usr/bin/ruby
puts 'Content-Type: text/html; charset=UTF-8' ; puts
html=<<'EOF'
<!doctype html>
<h1>おためしページ</h1>
<p>読めるかどうかためしてみよう</p>
EOF
puts html
パラメータを(HTTPのPUTメソッドで)受け取るコード(の、準備)
準備として、以下のようなフォームを使うHTMLページを想定する(このページはPCで開いてもいいしサーバに置いてもいい)
<!doctype html>
<meta charset="utf-8">
<form action="xxxx"> <!-- このactionについては後述)-->
文字列<input type="text" name="v">
を <input type="text" name="n">回
<input type="submit" value="表示 ">
</form>
(ソース)
前項の formタグのaction属性の値として呼び出されるサーバサイドプログラムを CGIで実現してみる。
上記HTMLファイルをPC側に置いて使うならば action属性の値として http://
から始まるURLを書く。HTMLファイルをサーバに置く(public_htmlの直下とする)なら ‘cgi-bin/yyy.rb’ のように、HTMLファイルを起点とした相対パス名を書くといい。
まずは以下のようなコードをaction側CGIとして置いてみよう。
#!/usr/bin/ruby
puts 'Content-Type: text/html' ; puts
p ENV['QUERY_STRING']
以下のコードはRuby独自のアプローチ。ただし、おそらく多くの言語で、下記を簡単に実現するライブラリ機能は提供されているので調べてみるといい。
分割
p qs=ENV['QUERY_STRING'].split('&') # 配列の形になる
p pm=Hash[*qs.map{|q|q.split('=')}.flatten]
これでHash(連想配列)の形になる(前期ライブラリのcgi.paramsも同様)。
デコード
前項の方法に代わるものとして、ライブラリ uri の機能を使う方法もある (URLデコードは任せられる)。
require 'uri'
p pms=URI.decode_www_form(ENV['QUERY_STRING'])
p pm=Hash[*pms.flatten]
p v=pm['v'] # 文字列が前提なのでHashの値をそのまま使う
p n=pm['n'].to_i # 整数としてデコード
使う
#!/usr/bin/ruby
# ここに前述のコードが(重複は整理して)入る
puts 'Content-Type: text/html; charset=UTF-8'; puts
# ここからHTML出力部
puts '<!doctype html>'
# 指定された文字列を指定回数出力
n.times do
puts "#{v}<br>"
end
puts '<a href="#" onclick="history.go(-1);return false">戻る</a>'
今日はここまで。
板書図: