Latest web development tutorials

python3 CGIプログラミング

CGIとは何ですか

次のように現在NCSAによって維持CGIは、NCSAのCGIが定義されています。

HTTPサーバ、同じHTMLページを提供するクライアント・インターフェース:のような、サーバー上で動作するプログラムであるCGI(Common Gateway Interface)を用い、共通ゲートウェイ・インターフェース、。


ウェブ閲覧

より良いCGIがどのように機能するかを理解するためには、プロセスのウェブページやURLのリンクをクリックすることができます:

  • 1、URLにアクセスして、HTTP Webサーバーに接続するには、ブラウザを使用しています。
  • 2、Webサーバは要求メッセージがURLを解析され、ファイルの内容を返すことがある場合、存在する場合、サーバー上でアクセスされたファイルを見て、それ以外の場合はエラーメッセージを返しますされます受け取ります。
  • 図3に示すように、ブラウザがサーバから情報を受信し、受信したファイルまたはエラーメッセージを表示します。

CGIプログラムは、Pythonスクリプト、Perlスクリプト、シェルスクリプト、CまたはC ++プログラムすることができます。


CGIチャート

cgiarch


Webサーバーの設定とサポート

あなたはCGIプログラミングを行う前に、ご使用のWebサーバーがCGIやCGIハンドラをサポートするように構成されていることを確認してください。

ApacheはCGIの設定をサポートしています。

CGIディレクトリを設定します。

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

CGIプログラムを実行するすべてのHTTPサーバは、予め設定されたディレクトリに格納されています。 このディレクトリには、CGIディレクトリと呼ばれ、慣習によって、それは、/ var / www /のcgi-binディレクトリという名前です。

CGIファイル拡張子.cgiの、パイソンもの.py拡張子を使用することができます。

デフォルトでは、のcgi-binディレクトリを実行するLinuxサーバーの設定は、は/ var / WWWのです。

あなたはCGIスクリプトを実行するために別のディレクトリを指定したい場合は、次のようにhttpd.confの設定ファイルを変更することができます。

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

.pyサフィックスのAddHandlerを追加しますので、我々は最後の.py Pythonスクリプトファイルにアクセスすることができます。

AddHandler cgi-script .cgi .pl .py

最初のCGIプログラム

次のように私たちは、ファイルは/ var / www /ののcgi-binディレクトリに配置され、hello.pyと呼ばれる最初のCGIプログラムを作成するためにPythonを使用します。

#!/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! 我是来自本教程的第一CGI程序</h2>')
print ('</body>')
print ('</html>')

あなたはファイルの更新hello.pyを保存した後、755へのファイルのパーミッションを変更します。

chmod 755 hello.py 

上記のプログラムは次のように結果がアクセスするためにブラウザに表示されます。

ブラウザの種類に送信し、 "text / htmlの"としてコンテンツを表示するためにブラウザに指示する:hello.pyこのスクリプトは、第1の出力ライン "text / htmlのコンテンツ・タイプ」のスクリプトは、単純なPythonスクリプトです。

空白行で印刷出力は、ヘッダ情報のサーバ側に伝えるために使用されます。


HTTPヘッダー

でhello.pyファイルの内容:HTTPヘッダの一部「コンテンツタイプtext / htmlの "ですが、それはブラウザのコンテンツタイプに送信されますブラウザのファイルを指示します。

次のようにHTTPヘッダーの形式は次のとおりです。

HTTP 字段名: 字段内容

例えば:

Content-type: text/html

次の表は、HTTPヘッダーのCGIプログラムの情報が頻繁に使用されて説明します。

ヘッド 説明
コンテンツタイプ: 情報要求に対応するMIMEエンティティ。 たとえば、次のようにコンテンツタイプ:text / htmlの
有効期限:日 回答日時の期限が切れ
場所:URL 新しいリソースの要求または識別を完了するために、非場所のURL要求に受信者をリダイレクトするには
最終更新:日 要求されたリソースが最後に変更されました
コンテンツの長さ:N Content-Length要求
Set-Cookieを:文字列 HTTPクッキーの設定

CGI環境変数

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

変数名 説明
CONTENT_TYPE この値は、情報転送のMIMEタイプに、その環境変数を示します。 現在では、環境変数は、一般的にCONTENT_TYPEです:アプリケーション/ x-www-form-urlencodedで、彼は、HTMLフォームからのデータと述べました。
CONTENT_LENGTH 転送モードサーバとCGIプログラム情報は、POSTの場合たとえ環境変数STDIN入力標準から有効なデータを読み込むことができるバイト数。 入力データを読み込むこの環境変数を使用する必要があります。
HTTP_COOKIE クライアント内COOKIEコンテンツ。
HTTP_USER_AGENT 情報を提供することは、クライアントのブラウザまたは他の独自のデータのバージョン番号が含まれています。
PATH_INFO この環境変数の値は、すぐに追加のパス情報の後にCGIプログラムの名前を示します。 これは、多くの場合、引数のCGIプログラムとして表示されます。
QUERY_STRING 転送モードサーバとCGIプログラムの情報は、情報である場合に渡された場合でも、この環境変数の値を取得します。 この情報は、両方の疑問符「?」セパレーターと途中で、CGIプログラムの名前が続きます。
REMOTE_ADDR この環境変数の値は、クライアントのIPアドレスは、例えば、上記の192.168.1.67の要求を送信します。 この値は常に存在しています。 Webサーバの一意の識別子をWebクライアントを提供する必要性が異なるWebクライアントを区別するためにCGIプログラムで使用することができるされています。
REMOTE_HOST この環境変数の値は、CGIの要求しているクライアントのホスト名が含まれています。 それはあなたがチェックしたくない場合は、この環境変数を定義する必要はありません。
REQUEST_METHOD これは、スクリプトと呼ばれる方法を提供します。 HTTP / 1.0プロトコルのスクリプトについてのみGETとPOST有意義。
SCRIPT_FILENAME CGIスクリプトへのフルパス
SCRIPT_NAME CGIスクリプトの名前
SERVER_NAME これは、Webサーバーのホスト名、エイリアス、またはIPアドレスです。
SERVER_SOFTWARE この環境変数の値は、HTTPサーバーのコールCGIプログラム名とバージョン番号が含まれています。 例えば、Apacheの/ 2.2.14(Unixの)の上の値

ここでは、簡単な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にファイルのパーミッションを変更し、次のように、実行結果は次のとおりです。


GETとPOSTメソッド

この方法は、GETとPOSTメソッドでどちらの二つの方法で情報を配信するサーバにブラウザクライアント。

データを転送するGETメソッドを使用します。

サーバに符号化されたユーザ情報を送信する方法をGET、データ情報は、以下のように分割数のページ要求のURLに含まれています「?」:

http://www.test.com/cgi-bin/hello.py?key1=value1&key2=value2
他のコメントのいくつかについての要求をGET:
  • GETリクエストをキャッシュすることができます
  • GETリクエストは、ブラウザの履歴に残ります
  • 要求はブックマークが可能GET
  • 機密データを扱う際の要求は使用すべきではありませんGET
  • GETリクエストは、長さの制限を持っています
  • 要求は、データを取得するために使用されるべきでGET

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

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

/cgi-bin/test.py?name=本教程&url=http://www.w3big.com

コード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>本教程 CGI 测试实例</title>")
print ("</head>")
print ("<body>")
print ("<h2>%s官网:%s</h2>" % (site_name, site_url))
print ("</body>")
print ("</html>")

あなたはファイルの更新hello_get.pyを保存した後、755へのファイルのパーミッションを変更します。

chmod 755 hello_get.py 

ブラウザは、出力を要求します。

単純な形式の例:GETメソッド

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

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>本教程(w3big.com)</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>

デフォルトでは、cgi-binディレクトリには、唯一のスクリプトファイルを保存することができ、我々は、テストディレクトリの下にあるファイルのパーミッションを755として格納さhello_get.html変更します:

chmod 755 hello_get.html

次のようにのGIFプレゼンテーションは、次のとおりです。

データを渡すためにPOSTメソッドを使用します。

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

以下は、それはまた、ブラウザから提出された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>本教程 CGI 测试实例</title>")
print ("</head>")
print ("<body>")
print ("<h2>%s官网:%s</h2>" % (site_name, site_url))
print ("</body>")
print ("</html>")

以下は、POSTメソッド(メソッド = "ポスト")することで、サーバースクリプトhello_get.pyにデータを送信するためのフォームです。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>本教程(w3big.com)</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>

次のようにのGIFプレゼンテーションは、次のとおりです。

チェックボックスを介してデータを渡すためのCGIプログラム

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

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>本教程(w3big.com)</title>
</head>
<body>
<form action="/cgi-bin/checkbox.py" method="POST" target="_blank">
<input type="checkbox" name="w3big" value="on" /> 本教程
<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('w3big'):
   w3big_flag = "是"
else:
   w3big_flag = "否"

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

checkbox.pyパーミッションを変更します。

chmod 755 checkbox.py

ブラウザアクセスのGIFプレゼンテーションチャート:

CGIプログラムを介して無線データ転送

以下のようにラジオが唯一のサーバにデータを転送し、HTMLコードは次のとおりです。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>本教程(w3big.com)</title>
</head>
<body>
<form action="/cgi-bin/radiobutton.py" method="post" target="_blank">
<input type="radio" name="site" value="w3big" /> 本教程
<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>本教程 CGI 测试实例</title>")
print ("</head>")
print ("<body>")
print ("<h2> 选中的网站是 %s</h2>" % site)
print ("</body>")
print ("</html>")

radiobutton.pyパーミッションを変更します。

chmod 755 radiobutton.py

ブラウザアクセスのGIFプレゼンテーションチャート:

CGIプログラムを介してテキストエリアの転送データ

テキストエリアには、次のようにHTMLコードは、サーバーに複数行のデータを渡します。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>本教程(w3big.com)</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>本教程 CGI 测试实例</title>")
print ("</head>")
print ("<body>")
print ("<h2> 输入的内容是:%s</h2>" % text_content)
print ("</body>")
print ("</html>")

textarea.py権限を変更します。

chmod 755 textarea.py

ブラウザアクセスのGIFプレゼンテーションチャート:

ドロップダウンパスデータをCGIプログラムを通じて。

HTMLドロップダウンボックスのコードを次のように

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>本教程(w3big.com)</title>
</head>
<body>
<form action="/cgi-bin/dropdown.py" method="post" target="_blank">
<select name="dropdown">
<option value="w3big" selected>本教程</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>本教程 CGI 测试实例</title>")
print ("</head>")
print ("<body>")
print ("<h2> 选中的选项是:%s</h2>" % dropdown_value)
print ("</body>")
print ("</html>")

dropdown.pyパーミッションを変更します。

chmod 755 dropdown.py

ブラウザアクセスのGIFプレゼンテーションチャート:


CGIはクッキーを使用されています

大きな欠点でHTTPプロトコルはプログラマに不便の多くを与えるユーザーのIDを、判断することが間違っているが、この不足のために作られたクッキーの機能を表示されます。

同一性を決定する機能を達成するように、クライアントのハードディスク上の顧客のブラウザを介して、顧客は、顧客は次のスクリプトを訪れたときにデータを取得し、データ・レコードを書き込むようにしながら、スクリプトにアクセスしているクッキーは、クッキーは、一般的に身元を検証する際に使用されます。

クッキーの構文

次のようにHTTPクッキーを達成するためにHTTPヘッダを介して送信され、彼はファイルを転送しなければならなかった、ヘッダのSet-Cookie構文は次のとおりです。

Set-cookie:name=name;expires=date;path=path;domain=domain;secure 
  • 複数名の値があります;("、"数名を使用することはできません"")、クッキーの値を設定する「;」は、 例えば 、分離する::名=名 NAME1 = NAME1; NAME2 = NAME2 ; NAME3 = NAME3。
  • 有効期限が切れる=日付:形式でクッキーの有効期限を:= "WDY、DD-期限が切れる:MM:SS月-YYYYのHHを"
  • パス=パス:パスがCookieサポートを設定し、パスがパスである場合、例えば力へのディレクトリエントリのすべてのファイルとサブディレクトリのCookie、:パス= "/のcgi-bin /"、パスがファイルである場合には、クッキーそれは例えば、このファイルの発効を指します。path = "/のcgi-bin / cookie.cgi」。
  • ドメイン=ドメイン:クッキーのドメイン名が有効で、例えば:ドメイン= "www.w3big.com"
  • 固定:このフラグが指定された場合、クッキーが唯一のSSLプロトコルHTTPSサーバを介して送信することができます。
  • クッキーは、クッキーの変数を検索して情報を取得することができ、環境変数HTTP_COOKIE達成CGIプログラムを設定することによって受信されます。

Cookieの設定

Cookieの設定CookieはHTTPヘッダで別々に送信され、非常に簡単です。 次の例では、名前を設定し、クッキーの有効期限:

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

cookie_set.py、およびcookie_set.py権限を変更するには、上記のコードを保存します。

chmod 755 cookie_set.py

上記の例はCookie情報を設定するには、Set-Cookieヘッダを使用し、オプションには、有効期限などのクッキー他の属性は、ドメインのドメイン、パスパスの有効期限設定しました。 この情報が提供されます。「コンテンツタイプtext / htmlの "前。


クッキー情報の取得

クッキー情報検索ページでは、Cookie情報が格納されている次のようにCGI環境変数HTTP_COOKIEに、ストレージ・フォーマットは、非常に簡単です:

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

ここでCookie情報を取得するための簡単なCGIプログラムは、次のとおりです。

#!/usr/bin/python3

# 导入模块
import os
import Cookie

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

print ("""
<html>
<head>
<meta charset="utf-8">
<title>本教程(w3big.com)</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_get.py、およびcookie_get.py権限を変更するには、上記のコードを保存します。

chmod 755 cookie_get.py

次のようにもっと色のGIFクッキーの設定は次のとおりです。

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

HTML にmultipart / form-dataに enctype属性を設定する必要性をアップロードする設定ファイルコード次のように:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>本教程(w3big.com)</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スクリプトファイルのコードは次のとおりです。

#!/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>本教程(w3big.com)</title>
</head>
<body>
   <p>%s</p>
</body>
</html>
""" % (message,))

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

chmod 755 save_file.py

次のようにもっと色のGIFクッキーの設定は次のとおりです。

あなたがUNIX / Linuxを使用している場合、あなただけのことができるオープン()ステートメントを使用する必要があるウィンドウでファイル区切りを置き換える必要があります。

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

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

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

機能コードを実装するためにHTTPヘッダ情報を設定してファイルをダウンロードし、以下の通りです。

#!/usr/bin/python3

# HTTP 头部
print ("Content-Disposition: attachment; filename=\"foo.txt\"")
print ()
# 打开文件
fo = open("foo.txt", "rb")

str = fo.read();
print (str)

# 关闭文件
fo.close()