Python
 Computer >> コンピューター >  >> プログラミング >> Python

Python CGIプログラミング入門:GETとPOSTメソッドの違いを徹底解説

GETとPOSTの2つのデータ送信方法

WebブラウザからWebサーバーを経由してCGIプログラムへ情報を渡したい場面は、開発において頻繁に発生します。ブラウザがサーバーに情報を送信する際、最も一般的に使われるのが「GETメソッド」と「POSTメソッド」の2つです。それぞれの仕組みと特徴を理解することは、安全で効率的なCGIプログラムを作る第一歩となります。

GETメソッドによるデータ送信

GETメソッドは、エンコードされたユーザー情報をページリクエスト自体に付加して送信する方式です。ページURLとエンコード済みデータは「?」記号で区切られ、以下のような形式になります。

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

GETメソッドはブラウザからサーバーへの情報伝達におけるデフォルトの方法であり、送信内容は長い文字列としてブラウザのアドレスバー(Locationボックス)に表示されます。そのため、パスワードやクレジットカード番号などの機密情報を扱う場合には絶対に使用しないでください

また、GETメソッドにはサイズ制限があり、リクエスト文字列として送れるのは最大1024文字までです。データはQUERY_STRINGヘッダー経由で送られ、CGIプログラム側ではQUERY_STRING環境変数として参照できます。

情報の渡し方としては、キーと値のペアを単純にURLに連結する方法と、HTMLの<FORM>タグを使う方法の2通りがあります。

シンプルなURLの例(GETメソッド)

次のURLは、GETメソッドを使って2つの値をhello_get.pyプログラムに渡す例です。

/cgi-bin/hello_get.py?first_name=ZARA&last_name=ALI

GETリクエストを処理するPythonスクリプト

以下は、ブラウザからの入力を処理するhello_get.pyスクリプトです。Python標準のcgiモジュールを使うと、渡された情報へのアクセスが非常に簡単になります。

#!/usr/bin/python
# CGI処理用モジュールをインポート
import cgi, cgitb

# FieldStorageインスタンスを作成
form = cgi.FieldStorage()

# フィールドからデータを取得
first_name = form.getvalue('first_name')
last_name = form.getvalue('last_name')

print "Content-type:text/html\r\n\r\n"
print "<html>"
print "<head>"
print "<title>Hello - Second CGI Program</title>"
print "</head>"
print "<body>"
print "<h2>Hello %s %s</h2>" % (first_name, last_name)
print "</body>"
print "</html>"

このスクリプトを実行すると、次のような結果が出力されます。

Hello ZARA ALI

HTMLフォームを使ったGET送信の例

次の例では、HTMLフォームと送信ボタンを使って2つの値を渡します。入力の処理には同じhello_get.pyスクリプトを使用します。

<form action = "/cgi-bin/hello_get.py" method = "get">
First Name: <input type = "text" name = "first_name"> <br />
Last Name: <input type = "text" name = "last_name" />
<input type = "submit" value = "Submit" />
</form>

上記フォームでは、名前(First Name)と姓(Last Name)を入力してSubmitボタンをクリックすると、結果が表示されます。

POSTメソッドによるデータ送信

CGIプログラムへ情報を渡す方法としては、一般により信頼性の高いPOSTメソッドが推奨されます。POSTはGETとまったく同じ形式でデータをパッケージ化しますが、URLの「?」以降にテキスト文字列として付加するのではなく、独立したメッセージとして送信する点が異なります。このメッセージは標準入力を通じてCGIスクリプトに渡されます。

POSTメソッドにはGETのようなサイズ制限がなく、URLにデータが表示されないため、大量のデータや機密情報の送信に適しています。

GETとPOSTの両方に対応したスクリプト

先ほどのhello_get.pyスクリプトは、実はGETメソッドとPOSTメソッドのどちらにも対応しています。cgiモジュールのFieldStorageが、リクエストメソッドを自動的に判別してくれるためです。

#!/usr/bin/python
# CGI処理用モジュールをインポート
import cgi, cgitb

# FieldStorageインスタンスを作成
form = cgi.FieldStorage()

# フィールドからデータを取得
first_name = form.getvalue('first_name')
last_name = form.getvalue('last_name')

print "Content-type:text/html\r\n\r\n"
print "<html>"
print "<head>"
print "<title>Hello - Second CGI Program</title>"
print "</head>"
print "<body>"
print "<h2>Hello %s %s</h2>" % (first_name, last_name)
print "</body>"
print "</html>"

HTMLフォームを使ったPOST送信の例

先ほどと同じフォームを、method属性を「post」に変更して使ってみましょう。処理するCGIスクリプトは同じhello_get.pyです。

<form action = "/cgi-bin/hello_get.py" method = "post">
First Name: <input type = "text" name = "first_name"><br />
Last Name: <input type = "text" name = "last_name" />
<input type = "submit" value = "Submit" />
</form>

こちらも同様に、First NameとLast Nameを入力してSubmitボタンを押すと結果が表示されます。

GETとPOSTの違いまとめ

項目GETメソッドPOSTメソッド
データの渡し方URLの末尾に「?」以降として付加リクエスト本文(標準入力)として送信
データ量の制限最大1024文字事実上制限なし
データの可視性アドレスバーに表示される表示されない
機密情報の扱い不向き適している
ブックマーク・履歴URLごと保存可能不可

補足:現代のPython環境について

なお、本記事で紹介しているcgiモジュールはPython 3.11で非推奨となり、Python 3.13で削除されました。現在の開発では、FlaskやDjangoといったWebフレームワークを使うか、WSGI準拠の手法を採用することが推奨されています。ただし、レガシーなシステムの保守やCGIの仕組みそのものを学ぶうえで、GETとPOSTの基本的な違いを理解しておくことは今でも非常に重要です。

  1. 【Python】Tkinterのroot.destroy()とroot.quit()の違いを徹底解説

    PythonのGUIライブラリ「Tkinter」では、アプリケーションを終了する方法として destroy() と quit() の2つのメソッドがよく使われます。似たような役割に見えますが、実際には動作が異なります。この記事では、それぞれの違いをサンプルコード付きでわかりやすく解説します。 root.destroy()とは tkinterのウィンドウオブジェクトに対して destroy() メソッドを呼び出すと、mainloop の処理が終了し、ウィンドウ内のすべてのウィジェットが破棄されます。つまり、ウィンドウそのものが完全に閉じられ、バックグラウンドで動作しているインタプリタ(Tcl/T

  2. Pythonのtkinterとtkinter.ttkウィジェットの違いとは?スタイリング方法を解説

    tkinter.ttkは、tkinterウィジェットのスタイル(見た目)を設定するためのモジュールです。HTML要素にCSSでデザインを適用するように、tkinter.ttkを使うことでtkinterウィジェットの外観を自由にカスタマイズできます。 tkinterウィジェットとtkinter.ttkの主な違い tkinterウィジェットは、ボタン・ラベル・テキスト・スクロールバーなど、基本的なGUI部品を追加するために使用します。一方、tkinter.ttkは標準のtkinterよりも多くの種類のウィジェットをサポートしています。 tkinter.ttkではPlaceやPack()、Grid