回答編集履歴

1 画像差し替え、文言一部修正

dodox86

dodox86 score 3370

2017/10/10 10:09  投稿

cgiの作り方ですが、今回のご質問のケースでは、以下のように進めれば良いかと思います。
1.「b.cgi」で処理した結果となるはずの、「a.html」だけをデザインの為に最初に造り、ブラウザで見た目を確認する。
1.「b.cgi」で処理した結果となるはずの、「a.html」だけをデザインの為に最初に作り、chromeなどのブラウザーで見た目を確認する。
具体的には、htmlのinput要素にvalueが加わったのがそれになります。
例:
```html
<input type="text" name="a" size="1" maxlength="1" value="1">
<input type="text" name="b" size="1" maxlength="1" value="2">
<input type="text" name="c" size="1" maxlength="1" value="3">
```
2.で造ったhtmlを吐き出すcgiプログラムを作成する。
cgiはformタグで指定されたものが呼び出されるわけですから、
`<form action="../cgi-bin/lec02.cgi" method="post">`
このケースの `"../cgi-bin/lec02.cgi"` が動いたときにname属性の各"a", "b", "c"の値を取り出して処理し、更にHTTPレスポンスのコンテントボディとして返すhtml中のvalueにセットして、printで出力すれば良い、と言うことになります。
このケースの `"../cgi-bin/lec02.cgi"` が動いたときにname属性の各"a", "b", "c"の値を取り出して処理し、更にHTTPレスポンスのコンテントボディとして返すhtml中のvalue属性にセットして、printで出力すれば良い、と言うことになります。
要は、a.htmlをテンプレートとして、valueの部分のみを差し替えてhtmlとして出力するプログラムにすれば良いわけです。
実例として、lec02.cgiをサンプルとして作ってみましたので参考になさってください。htmlは「実現したいことの一部...」をほぼそのままテンプレートとして使います。cgiとして動いていることが分かりやすいよう、フォームをサブミットすると現在日時の表示と、フォームのinput部分に数字を入れれば+1, そうでなければそのまま出力するようにしています。Python3で作成しています。
```Python
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# cgi-bin/lec02.cgi
import cgi
import datetime
html_format = """
<html>
   <head>
       <meta http-equiv="Content-Type" content=\"text/html\"; charset="UTF-8\" />
   </head>
   <body>
       <div align="center">
       <form action="../cgi-bin/lec02.cgi" method="post">
       <table border=2>
           <tr>{0}</tr>
           <tr>
               <th>暗号</th>
               <th>A</th>
               <th>B</th>
               <th>C</th>
           <tr>
           <tr><th>復号</th>
               <td><input type="text" name="a" size="1" maxlength="1" value="{1}"></td>
               <td><input type="text" name="b" size="1" maxlength="1" value="{2}"></td>
               <td><input type="text" name="c" size="1" maxlength="1" value="{3}"></td>
           </tr>
       </table>
       <input type="submit" value="復号">
       </form>
       </div>
   </body>
</html>
"""
# formにセットされた値を取得
form = cgi.FieldStorage()
# 値が数字なら+1, 文字列ならそのまま
v1 = form.getvalue('a')
if v1:
   if v1.isdigit():
       v1 = int(v1) + 1
else:
   v1 = ""
v2 = form.getvalue('b')
if v2:
   if v2.isdigit():
       v2 = int(v2) + 1
else:
   v2 = ""
v3 = form.getvalue('c')
if v3:
   if v3.isdigit():
       v3 = int(v3) + 1
else:
   v3 = ""
# 現在日時を取得
now = datetime.datetime.now()
print("Content-Type: text/html")
print()
# 現在日時、v1,v2,v3をhtmlにセット
html = html_format.format(now, v1, v2, v3)
print(html)
```
動作確認の一例ですが、lec02.cgi を cgi-bin/ディレクトリ下に置き、「実現したいことの一部...」のhtmlをdoc/top.html として配置します。
```Bash
$ find ./
./
./cgi-bin
./cgi-bin/lec02.cgi
./doc
./doc/top.html
$ python3 -m http.server --cgi
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
```
上記のように動かした場合、ブラウザーからは以下のどちらのURLからでもアクセスできます。
http://localhost:8000/doc/top.html (トップページとして表示)
http://localhost:8000/cgi-bin/lec02.cgi
chromeブラウザーで見ると、以下のように表示されます。
![イメージ説明](a27a8f0f3696492e36d66732572168b6.png)
![イメージ説明](31c71e007efd1e46193cc492e1cb0521.png)
python3でのcgiですが、サンプルのlec02.cgiは「**formの値を取り出して、htmlで返せば良い**」と言うことを示す為に、分かり易くあえて冗長に造ったところもありますので、公式の文書を読んでみてください。
[21.2. cgi — CGI (ゲートウェイインタフェース規格) のサポート](https://docs.python.jp/3/library/cgi.html)

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る