Python3 CGIプログラミング



CGIとは

CGIは現在NCSAによって管理されています。NCSAはCGIを次のように定義しています:

CGI (Common Gateway Interface)、共通ゲートウェイインターフェース、HTTPサーバーなどのサーバー上で実行されるプログラムです。同じクライアント HTML ページ インターフェイス。


Web ブラウズ

CGI の仕組みをよりよく理解するには、Web ページ上のリンクまたは URL をクリックするプロセスから始めます。

  • 1. ブラウザを使用して URL にアクセスし、HTTP Web に接続します。サーバ。

  • 2. リクエスト情報を受信した後、Web サーバーは URL を解析し、アクセスされたファイルがサーバー上に存在するかどうかを確認します。ファイルが存在する場合は、ファイルの内容を返します。存在しない場合は、エラー メッセージが返されます。 。

  • 3. ブラウザはサーバーから情報を受信し、受信したファイルやエラーメッセージを表示します。

CGI プログラムは、Python スクリプト、PERL スクリプト、SHELL スクリプト、C または C++ プログラムなどです。


CGI アーキテクチャ図

Cgi01.png


Web サーバーのサポートと構成

CGI プログラミングを実行する前に、Web サーバーが CGI をサポートし、CGI ハンドラーが構成されていることを確認してください。

Apache は CGI 構成をサポートします:

CGI ディレクトリをセットアップします:

ScriptAlias /cgi-bin/ /var/www/cgi-bin/

すべての HTTP サーバー実行 CGI プログラムは、事前に構成されたディレクトリに保存されます。このディレクトリは CGI ディレクトリと呼ばれ、慣例により /var/www/cgi-bin という名前が付けられます。

CGI ファイルの拡張子は .cgi ですが、Python では .py 拡張子も使用できます。

デフォルトでは、Linux サーバーが実行するように設定されている cgi-bin ディレクトリは /var/www です。

CGI スクリプトを実行する他のディレクトリを指定したい場合は、httpd.conf 構成ファイルを次のように変更できます:

<Directory "/var/www/cgi-bin">
   AllowOverride None
   Options +ExecCGI
   Order allow,deny
   Allow from all
</Directory>

AddHandler に .py サフィックスを追加して、.py で終わる Python スクリプト ファイルにアクセスできるようにします:

AddHandler cgi-script .cgi .pl .py

最初の CGI プログラム

最初の CGI プログラムを作成するには、ファイル名は hello.py です。ファイルの内容は次のとおりです。

#!/usr/bin/python3

print ("Content-type:text/html")
print ()                             # 空行,告诉服务器结束头部
print ('<html>')
print ('<head>')
print ('<meta charset="utf-8">')
print ('<title>Hello Word - 我的第一个 CGI 程序!</title>')
print ('</head>')
print ('<body>')
print ('<h2>Hello Word! 我是来自php中文网的第一CGI程序</h2>')
print ('</body>')
print ('</html>')

ファイル hello.py を保存した後に変更し、ファイルのアクセス許可を 755 に変更します。

chmod 755 hello.py

上記のプログラムは、ブラウザでアクセスすると次の結果を表示します:

1026.jpg

この hello.py スクリプトは単純な Python スクリプトです。 、スクリプトの最初の行の出力コンテンツは「Content -type:text/html」です。これはブラウザに送信され、表示されるコンテンツ タイプが「text/html」であることをブラウザに伝えます。

print を使用して空行を出力し、サーバーにヘッダー情報を終了するように指示します。


HTTP ヘッダー

hello.py ファイルのコンテンツ "Content-type: text/html" は HTTP ヘッダーの一部であり、ファイルのコンテンツ タイプをブラウザーに伝えるためにブラウザーに送信されます。

HTTP ヘッダーの形式は次のとおりです:

HTTP 字段名: 字段内容

例:

Content-type: text/html

次の表は、CGI プログラムの HTTP ヘッダーで一般的に使用される情報を示しています。
HeaderDescription
Content-type:エンティティに対応する要求された MIME 情報。例: Content-type: text/html
Expires: Date応答の有効期限が切れる日時
Location: URL受信者をリクエストされていない URL の場所にリダイレクトするために使用されます。リクエストを完了するか、新しいリソースを特定します
Last-modified: Dateリクエストされたリソースの最終変更時刻
Content-length: Nリクエストされたコンテンツの長さ
Set-Cookie: String HTTP Cookie を設定する

CGI 環境変数

すべての CGI プログラムは、CGI プログラムで重要な役割を果たす次の環境変数を受け取ります:

SERVER_SOFTWARE

以下は CGI 環境変数を出力する簡単な CGI スクリプトです:

#!/usr/bin/python3

import os

print ("Content-type: text/html")
print ()
print ("<meta charset=\"utf-8\">")
print ("<b>环境变量</b><br>")
print ("<ul>")
for key in os.environ.keys():
    print ("<li><span style='color:green'>%30s </span> : %s </li>" % (key,os.environ[key]))
print ("</ul>")

上記の点を test.py として保存し、ファイルのアクセス許可を 755 に変更します。 実行結果は次のとおりです:

1027.jpg


GET と POSTメソッド

Browse サーバークライアントは、GET メソッドと POST メソッドの 2 つのメソッドを通じてサーバーに情報を送信します。

データを送信するには GET メソッドを使用します

GET メソッドは、以下に示すように、エンコードされたユーザー情報をリクエスト ページの URL に「?」で区切って含めて送信します。 GET リクエストに関する情報 注:

  • GET リクエストはキャッシュに保存できます

  • GET リクエストはブラウザの履歴に残ります

  • GET リクエストはブックマークできます

  • GET リクエストは機密データを扱う場合には使用しないでください

  • GET リクエストには長さ制限があります

  • GET リクエストはデータを取得するためにのみ使用してください

単純な URL の例: GET メソッド

以下は、GET メソッドを使用して 2 つの URL を hello_get に送信する単純な URL です。 .py プログラム パラメーター:

http://www.test.com/cgi-bin/hello.py?key1=value1&key2=value2

以下は hello_get.py ファイルのコードです:

/cgi-bin/test.py?name=php中文网&url=http://www.php.cn

ファイルを保存した後、hello_get.py を変更し、ファイルのアクセス許可を 755 に変更します:

#!/usr/bin/python3

# CGI处理模块
import cgi, cgitb 

# 创建 FieldStorage 的实例化
form = cgi.FieldStorage() 

# 获取数据
site_name = form.getvalue('name')
site_url  = form.getvalue('url')

print ("Content-type:text/html")
print ()
print ("<html>")
print ("<head>")
print ("<meta charset=\"utf-8\">")
print ("<title>php中文网 CGI 测试实例</title>")
print ("</head>")
print ("<body>")
print ("<h2>%s官网:%s</h2>" % (site_name, site_url))
print ("</body>")
print ("</html>")

ブラウザー要求の出力結果:

1028.jpg

簡単なフォームの例: GET メソッド

以下は、HTML を使用して GET メソッドを使用して 2 つのデータをサーバーに送信するフォームです。送信されたサーバー スクリプトも hello_get.py ファイルであり、hello_get.html コードは次のとおりです。以下:

chmod 755 hello_get.py

デフォルトでは、cgi-bin ディレクトリはスクリプト ファイルのみを保存できます。 hello_get.html を test ディレクトリに保存し、ファイルのアクセス許可を 755 に変更します。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>php中文网(php.cn)</title>
</head>
<body>
<form action="/cgi-bin/hello_get.py" method="get">
站点名称: <input type="text" name="name">  <br />

站点 URL: <input type="text" name="url" />
<input type="submit" value="提交" />
</form>
</body>
</html>

Gif デモは次のとおりです。

POST メソッドを使用してデータを転送しますhello_get.gif

POST メソッドを使用してデータをサーバーに転送します。ユーザーのパスワードなどの一部の機密情報はデータの送信に POST を使用する必要があるため、より安全で信頼性が高くなります。

以下も hello_get.py で、ブラウザーによって送信された POST フォーム データを処理することもできます:

chmod 755 hello_get.html

以下は、POST メソッド (

method="post) を通じてサーバー スクリプト hello_get.py にデータを送信するフォームです。 "

):

#!/usr/bin/python3

# CGI处理模块
import cgi, cgitb 

# 创建 FieldStorage 的实例化
form = cgi.FieldStorage() 

# 获取数据
site_name = form.getvalue('name')
site_url  = form.getvalue('url')

print ("Content-type:text/html")
print ()
print ("<html>")
print ("<head>")
print ("<meta charset=\"utf-8\">")
print ("<title>php中文网 CGI 测试实例</title>")
print ("</head>")
print ("<body>")
print ("<h2>%s官网:%s</h2>" % (site_name, site_url))
print ("</body>")
print ("</html>")
GIF デモは次のとおりです:

CGI プログラムを通じてチェックボックス データを転送します hello_post.gif

チェックボックスは 1 つ以上のオプション データを送信するために使用されます。HTML コードは次のとおりです:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>php中文网(php.cn)</title>
</head>
<body>
<form action="/cgi-bin/hello_get.py" method="post">
站点名称: <input type="text" name="name">  <br />

站点 URL: <input type="text" name="url" />
<input type="submit" value="提交" />
</form>
</body>
</html>
</form>

以下はcheckbox.py ファイルのコード:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>php中文网(php.cn)</title>
</head>
<body>
<form action="/cgi-bin/checkbox.py" method="POST" target="_blank">
<input type="checkbox" name="php" value="on" /> php中文网
<input type="checkbox" name="google" value="on" /> Google
<input type="submit" value="选择站点" />
</form>
</body>
</html>

checkbox.py 権限の変更:

#!/usr/bin/python3

# 引入 CGI 处理模块 
import cgi, cgitb 

# 创建 FieldStorage的实例 
form = cgi.FieldStorage() 

# 接收字段数据
if form.getvalue('google'):
   google_flag = "是"
else:
   google_flag = "否"

if form.getvalue('php'):
   php_flag = "是"
else:
   php_flag = "否"

print ("Content-type:text/html")
print ()
print ("<html>")
print ("<head>")
print ("<meta charset=\"utf-8\">")
print ("<title>php中文网 CGI 测试实例</title>")
print ("</head>")
print ("<body>")
print ("<h2> php中文网是否选择了 : %s</h2>" % php_flag)
print ("<h2> Google 是否选择了 : %s</h2>" % google_flag)
print ("</body>")
print ("</html>")

ブラウザ アクセス Gif デモ画像:

CGI プログラムを通じてラジオ データを転送する

ラジオは 1 つのデータのみをサーバーに転送します。HTML コードは次のとおりです:

chmod 755 checkbox.py

radiobutton.py スクリプト コードは次のとおりです:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>php中文网(php.cn)</title>
</head>
<body>
<form action="/cgi-bin/radiobutton.py" method="post" target="_blank">
<input type="radio" name="site" value="php" /> php中文网
<input type="radio" name="site" value="google" /> Google
<input type="submit" value="提交" />
</form>
</body>
</html>

radiobutton.py を変更する 権限:

#!/usr/bin/python3

# 引入 CGI 处理模块 
import cgi, cgitb 

# 创建 FieldStorage的实例 
form = cgi.FieldStorage() 

# 接收字段数据
if form.getvalue('site'):
   site = form.getvalue('site')
else:
   site = "提交数据为空"

print ("Content-type:text/html")
print ()
print ("<html>")
print ("<head>")
print ("<meta charset=\"utf-8\">")
print ("<title>php中文网 CGI 测试实例</title>")
print ("</head>")
print ("<body>")
print ("<h2> 选中的网站是 %s</h2>" % site)
print ("</body>")
print ("</html>")

ブラウザアクセス Gif デモ画像:

radiobutton.gif

CGI プログラムを介して Textarea データを転送します

Textarea は、複数行のデータをサーバーに転送します。 HTML コードは次のとおりです:

chmod 755 radiobutton.py

textarea.py スクリプト コードは次のとおりです。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>php中文网(php.cn)</title>
</head>
<body>
<form action="/cgi-bin/textarea.py" method="post" target="_blank">
<textarea name="textcontent" cols="40" rows="4">
在这里输入内容...
</textarea>
<input type="submit" value="提交" />
</form>
</body>
</html>

textarea.py を変更する 権限:

#!/usr/bin/python3

# 引入 CGI 处理模块 
import cgi, cgitb 

# 创建 FieldStorage的实例 
form = cgi.FieldStorage() 

# 接收字段数据
if form.getvalue('textcontent'):
   text_content = form.getvalue('textcontent')
else:
   text_content = "没有内容"

print ("Content-type:text/html")
print ()
print ("<html>")
print ("<head>")
print ("<meta charset=\"utf-8\">")
print ("<title>php中文网 CGI 测试实例</title>")
print ("</head>")
print ("<body>")
print ("<h2> 输入的内容是:%s</h2>" % text_content)
print ("</body>")
print ("</html>")

ブラウザ アクセス Gif デモンストレーション:

textarea.gif

CGI プログラムを介してドロップダウン データを転送します。

HTML ドロップダウン ボックスのコードは次のとおりです:

chmod 755 textarea.py

dropdown.py スクリプト コードは次のとおりです:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>php中文网(php.cn)</title>
</head>
<body>
<form action="/cgi-bin/dropdown.py" method="post" target="_blank">
<select name="dropdown">
<option value="php" selected>php中文网</option>
<option value="google">Google</option>
</select>
<input type="submit" value="提交"/>
</form>
</body>
</html>

dropdown.py の変更 権限:

#!/usr/bin/python3

# 引入 CGI 处理模块 
import cgi, cgitb 

# 创建 FieldStorage的实例 
form = cgi.FieldStorage() 

# 接收字段数据
if form.getvalue('dropdown'):
   dropdown_value = form.getvalue('dropdown')
else:
   dropdown_value = "没有内容"

print ("Content-type:text/html")
print ()
print ("<html>")
print ("<head>")
print ("<meta charset=\"utf-8\">")
print ("<title>php中文网 CGI 测试实例</title>")
print ("</head>")
print ("<body>")
print ("<h2> 选中的选项是:%s</h2>" % dropdown_value)
print ("</body>")
print ("</html>")

ブラウザ アクセス Gif デモ画像:

dropdown.gif


CGI で使用される Cookie

http プロトコルの大きな欠点は、ユーザーの身元を判断しないことであり、プログラマにとっては非常に不便です。 この欠点を補うのがCookie機能の登場です。

Cookieとは、お客様がスクリプトにアクセスした際に、お客様のブラウザを通じてお客様のハードディスクに記録データを書き込むものです。 、次回お客様がスクリプトにアクセスしたときにデータ情報が取得され、本人確認機能を実現するために Cookie がよく使用されます。

Cookie 構文

http Cookie は、ファイル転送よりも先に http ヘッダーを通じて送信されます。ヘッダー内の set-cookie の構文は次のとおりです:

chmod 755 dropdown.py

  • name=name: Cookie は次のとおりです。値を設定します (名前には「;」と「,」は使用できません)。複数の名前の値がある場合は、「;」を使用して区切ります。例: name1=name1;name2=name2;name3 =名前3

  • expires=date: Cookieの有効期間、形式:expires="Wdy,DD-Mon-YYYY HH:MM:SS"


  • path=path: Cookieの設定 サポートされていますpath がパスの場合、Cookie はこのディレクトリ内のすべてのファイルとサブディレクトリに対して有効になります。たとえば、path="/cgi-bin/" です。 path がファイルの場合、Cookie はこのファイルに対して有効になります。例: path="/cgi-bin/cookie.cgi"。

  • domain=domain: Cookie に有効なドメイン名。たとえば、domain="www.php.cn"

  • secure: このフラグが指定されている場合、それは、 Cookie は SSL プロトコル サーバーの https を通過してのみ配信できます。

  • Cookie の受信は環境変数 HTTP_COOKIE を設定することで実現され、CGI プログラムはこの変数を取得することで Cookie 情報を取得できます。


Cookieの設定

Cookieの設定は非常に簡単で、Cookieはhttpヘッダーで個別に送信されます。次の例では、Cookie に名前と有効期限を設定します。

Set-cookie:name=name;expires=date;path=path;domain=domain;secure

上記のコードを cookie_set.py に保存し、cookie_set.py のアクセス許可を変更します。

#!/usr/bin/python3
# 
print ('Content-Type: text/html')
print ('Set-Cookie: name="php中文网";expires=Wed, 28 Aug 2016 18:30:00 GMT')
print ()
print ("""
<html>
  <head>
    <meta charset="utf-8">
    <title>php中文网(php.cn)</title>
  </head>
    <body>
        <h1>Cookie set OK!</h1>
    </body>
</html>
""")

上記の例では、Set-Cookie ヘッダー情報を使用して、Cookie 情報、オプションのその他の属性を設定します。有効期限 Expires、ドメイン名、パスなどの Cookie が設定されます。この情報は「Content-type:text/html」の前に設定されます。


Cookie情報の取得

Cookie情報の取得ページは非常にシンプルで、CGI環境変数HTTP_COOKIEに格納されます。保存形式は次のとおりです。

chmod 755 cookie_set.py

以下はCookie情報を取得するための簡単なCGIプログラムです。

key1=value1;key2=value2;key3=value3....

上記を置き換えます コードを cookie_get.py に保存し、cookie_get.py のアクセス許可を変更します:

#!/usr/bin/python3

# 导入模块
import os
import Cookie

print ("Content-type: text/html")
print ()

print ("""
<html>
<head>
<meta charset="utf-8">
<title>php中文网(php.cn)</title>
</head>
<body>
<h1>读取cookie信息</h1>
""")

if 'HTTP_COOKIE' in os.environ:
    cookie_string=os.environ.get('HTTP_COOKIE')
    c=Cookie.SimpleCookie()
    c.load(cookie_string)

    try:
        data=c['name'].value
        print ("cookie data: "+data+"<br>")
    except KeyError:
        print ("cookie 没有设置或者已过去<br>")
print ("""
</body>
</html>
""")

上記の Cookie 設定の色の Gif は次のとおりです:

cookie.gif

ファイルのアップロードの例

HTML 設定 ファイルをアップロードするためのフォーム設定する必要があります

enctype 属性は multipart/form-data、コードは次のとおりです:

chmod 755 cookie_get.py

save_file.py スクリプト ファイルのコードは次のとおりです:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>php中文网(php.cn)</title>
</head>
<body>
 <form enctype="multipart/form-data" 
                     action="/cgi-bin/save_file.py" method="post">
   <p>选中文件: <input type="file" name="filename" /></p>
   <p><input type="submit" value="上传" /></p>
   </form>
</body>
</html>

上記のコードを save_file.py に保存し、 save_file.py の権限を変更します。

#!/usr/bin/python3

import cgi, os
import cgitb; cgitb.enable()

form = cgi.FieldStorage()

# 获取文件名
fileitem = form['filename']

# 检测文件是否上传
if fileitem.filename:
   # 设置文件路径 
   fn = os.path.basename(fileitem.filename)
   open('/tmp/' + fn, 'wb').write(fileitem.file.read())

   message = '文件 "' + fn + '" 上传成功'
   
else:
   message = '文件没有上传'
   
print ("""\
Content-Type: text/html\n
<html>
<head>
<meta charset="utf-8">
<title>php中文网(php.cn)</title>
</head>
<body>
   <p>%s</p>
</body>
</html>
""" % (message,))

以下に示すように、上の Cookie のカラー Gif を設定します。

savefile.gif

使用しているシステムが Unix/Linux の場合は、ウィンドウの下のファイル区切り文字を置き換える必要があります。 open() ステートメントを使用するには:

chmod 755 save_file.py


ファイルダウンロードダイアログボックス

us まず、プログラムをダウンロードするために現在のディレクトリに foo.txt ファイルを作成します。

ファイルのダウンロードはHTTPヘッダー情報を設定することで実現します。関数コードは以下の通りです:

fn = os.path.basename(fileitem.filename.replace("\", "/" ))

変数名説明
コンテンツタイプ この環境変数の値は、渡される情報の MIME タイプを示します。現在、環境変数 CONTENT_TYPE は通常、application/x-www-form-urlencoded であり、データが HTML フォームから取得されることを示します。
CONTENT_LENGTHサーバーとCGIプログラム間の情報伝達方式がPOSTの場合、この環境変数は標準入力STDINから読み取れる有効なデータのバイト数になります。この環境変数は、入力されたデータを読み取るときに使用する必要があります。クライアント内の
HTTP_COOKIECOOKIEコンテンツ。
HTTP_USER_AGENTバージョン番号やその他の独自データを含む顧客のブラウザ情報を提供します。
PATH_INFO この環境変数の値は、CGI プログラム名の直後の他のパス情報を表します。多くの場合、CGI プログラムのパラメータとして表示されます。
QUERY_STRINGサーバーとCGIプログラム間の情報転送方式がGETの場合、この環境変数の値が転送される情報となります。この情報は、CGI プログラム名の後に疑問符「?」で区切って続きます。
REMOTE_ADDR この環境変数の値は、リクエストを送信するクライアントの IP アドレス (上記の 192.168.1.67 など) です。この値は常に存在します。これは、Web クライアントが Web サーバーに提供する必要がある一意の識別子であり、CGI プログラムでさまざまな Web クライアントを区別するために使用できます。
REMOTE_HOST この環境変数の値には、CGI リクエストを送信したクライアントのホスト名が含まれます。クエリしたいクエリがサポートされていない場合、この環境変数を定義する必要はありません。
REQUEST_METHOD スクリプトを呼び出すメソッドを提供します。 HTTP/1.0 プロトコルを使用するスクリプトの場合、GET と POST のみが意味を持ちます。
script_fileNameCCGIスクリプトのフルパスcgiスクリプトの名前の名前は、Webサーバーのホスト名、エイリアス、またはIPアドレスです。
この環境変数の値には、CGI プログラムを呼び出す HTTP サーバーの名前とバージョン番号が含まれます。たとえば、上記の値は Apache/2.2.14(Unix) です