コンテンツにスキップ

PythonのCGIでリダイレクトができない解決策

[質問]

Pythonのhttp.serverのCGIでは、301リダイレクトができないため、「フォームのPOSTを処理したあとにすぐ元のページに戻る」という、よくある処理ができません。これは「古い時代の技術を学ぼう」という趣旨なので、ダメならダメでよいのですが、もし解決策があるなら聞いてみたいです。

[回答] Gemini

「あえて古い技術を学ぶ」という姿勢、素晴らしいですね!不便さを知ることで、現代のフレームワーク(FlaskやFastAPIなど)がいかに痒いところに手が届くようになっているかを実感できるので、非常に教育的だと思います。

結論から言うと フロントエンド側の力技 を使えば解決可能です。

いくつかのアプローチを紹介します。


1. HTMLの「Meta Refresh」を使う(レトロ・テクニック)

HTTPヘッダーの制御がうまくいかない場合、あるいは「いかにも昔のウェブ」らしい挙動にしたい場合は、HTMLの機能を使います。処理が終わったあとに、「リダイレクト用のHTML」を書き出す方法です。

#!/usr/bin/env python3

# フォーム処理...

print("Content-Type: text/html\n")
print("""
<html>
    <head>
        <meta http-equiv="refresh" content="0;url=./index.html">
    </head>
    <body>
        <p>処理が完了しました。画面が切り替わらない場合は<a href="./index.html">こちら</a>をクリックしてください。</p>
    </body>
</html>
""")

これは 「Meta Refresh」 と呼ばれる手法で、90年代から2000年代初頭の個人サイトで「移転しました。5秒後にジャンプします」という画面でよく見られた、非常に「趣のある」解決策です。


2. JavaScriptで無理やり飛ばす(現代的アプローチ)

スクリプトからJSを出力して、ブラウザの機能でページ遷移させます。

print("Content-Type: text/html\n")
print("<script>window.location.href = './index.html';</script>")

「フォームPOST後のリダイレクト」の重要性

質問にある「POSTしたあとに戻る」処理は、専門用語で PRGパターン (Post-Redirect-Get) と呼びます。

豆知識: これをやらずにHTMLを直接返してしまうと、ユーザーがブラウザで「更新(F5)」を押したときに、「フォームを再送信しますか?」という警告が出て、二重投稿の原因になります。1990年代から続く、Web開発の「伝統芸能」的なお作法です。

この「あえて古い技術で苦労する」過程で、HTTPプロトコルの生々しい仕組みが見えてくるはずです。


まとめ:どれが「趣」に合うか?

「古い時代の技術を学ぶ」という趣旨であれば、1番の Meta Refresh が最もその時代の雰囲気を味わえるかもしれません。当時の掲示板(BBS)などのCGIスクリプトでは、処理完了画面を数秒見せてから元のページに戻す手法が一般的でした。

もし、この「不便なCGI開発」の中で、特定の挙動(例えばデータの受け渡しなど)で詰まっている部分があれば、さらに深掘りしてお手伝いできますよ。

次は、SQLiteなどを使ったデータの保存処理についても見てみますか?