WEBアプリケーションを作る4ーFlask編ーくじ引きアプリ、WEBの基礎について
どうもhiroakiです。
前回に引き続き、Flaskを使ったWEBアプリケーションを作る方法を紹介します。読まれてない人は前回の記事もご参考ください。HTMLとCSSについては以下を参考ください。
WEBの基礎
WEBで特に押さえるべきはHTML、HTTP、URLの3つです。HTMLについては前回の記事を読まれている人なら、もう大丈夫ですね。心配な人は戻って読まれることをおすすめします。
ではまず、HTTPについて説明していきます。ちなみに前回、「WEBの世界はシンプルです」とお伝えしましたが、覚えていますか。
まだ、覚えてないという人はしっかり覚えてくださいね。実は、上記が成立するためには、HTTPが必要になります。HTTP(HyperText Transfer Protocol)とは「HyperText」のデータをやり取りするためのプロトコル(決まりごと)と理解してください。英語部分を読んでもらえれば、そのままの意味になっていますね。
HTTPでのデータ送受信は、クライアントとWebサーバーの間で行われます。クライアントは「HTTPリクエスト」をWebサーバーに送信し、サーバーはそのリクエストを処理して「HTTPレスポンス」をクライアントに返却します。
代表的なクライアントは、ブラウザーです。ブラウザーはHTTPに乗っ取ってデータの送受信をしWebページを表示しています。大まかにいうと、ブラウザーは下記の順序でWebサーバーとデータをやりとりします。
- ブラウザーはHTTPリクエストのメッセージを組み立てる
- ブラウザーはURL(Webサーバー)に対してHTTPリクエストを送信する
- WebサーバーはHTTPリクエストを解析する
- Webサーバーはリクエストの内容に応じたHTTPレスポンスを組み立てる
- WebサーバーはHTTPレスポンスをブラウザーに返却する
- ブラウザーは受け取ったHTTPレスポンスを解析する
- ブラウザーは解析した内容を画面に表示する(HTMLであればレンダリングrenderして表示する)
「HTTPリクエスト」は単純にコンテンツを取得する以外の方法も提供します。その方法のことを「HTTPメソッド」と呼びます。主なメソッドは以下の通りです。
GET...Webサーバーに対してヘッダーとコンテンツ双方をリクエスト
POST...Webサーバーに対して新しいデータを送信
HEAD ... Webサーバーに対してヘッダーのみを要求
PUT ... Webサーバーにある既存のデータを更新する
DELETE ... Webサーバーにある既存のデータを削除する
「http://」の部分をスキーマと呼びます。データをやり取りするための手段だとイメージしてください。httpとなっているので、上記で説明したHTTPでデータをやりとりするという意味です。ちなみに、http以外にもftpやmailto、fileなどさまざまなデータに合わせたスキーマが存在します。
「www.google.co.jp」はホスト名です。ホストとは、そのコンテンツを管理するサーバなどを指します。ホスト名は「ドメイン」や「IPアドレス」などで表現されます。
「/search?q=Python」は具体的なコンテンツの名前です。ホスト内部でのファイルパスを示します。
参考文献:
docs.pyq.jp
POSTについての補足説明
さて、前回POSTを使用した場合のコーディングについて書きました。実は、前回のコード例だとちょっとした問題が起こるんです。
フォームの二重送信問題について
入力画面(result.html)から画面を遷移できたら(output.html)、ブラウザーを更新してみてください。「フォームを再送信してもよろしいですか?」という意味合いのメッセージが表示されるはずです。
ここで再送信を選択すると二重送信という状態になります。
実際のWebシステムに当てはめると、購入や課金が二重に処理されるということになります。
データ送信後に遷移する/outputを更新すると、関数outputが実行されてPOSTによるデータ送信が再度なされます。これが二重送信が起きている理由です。
リダイレクトとは
プログラムによって自動的に遷移させることをリダイレクト(Redirect) と呼びます。リダイレクトを使うことで、画面を更新することによる二重送信を防げます。
リダイレクトを使うと、ユーザーを別のページへ自動的に移動できます。URLが変更されたWebサイトのコンテンツがあったとして、古いURLにアクセスしてきたユーザーを新しいURLに誘導する、というような使い方をします。
例えばresult.htmlの<form>タグでmethod="post"を指定して、main.pyに以下のコードを作ります。
- from flask import Flask, redirect,render_template,
- request,url_for
- app = Flask(__name__)
- @app.route("/")
- def index():
- return render_template('input.html')
- @app.route("/output", methods=['POST'])
- def output():
- your_name = request.form['name']
- return redirect(url_for('redirect_test',name=your_name))
- @app.route("/redirect_test",methods=['GET'])
- def redirect_test():
- your_name=request.args.get('name','')
- return render_template('output.html', name=your_name)
これ見てもらうと分かる通り、postで受け取ったnameの値をgetで受け直してるんですね。そうすることで、二重送信問題を回避しています。このときユーザーには/から/redirect_testに直接移動したように見えますが、実際には/と/redirect_testの間には/outputというURLがあり、そこを介して遷移していることになります。
今回は以上です。何度も繰り返して理解しましょう。
皆さんの疑問を、ちょっとずつ紐解いていけてると嬉しいです。次回も続きをやっていきますので、不明点等ありましたら、気軽にコメントください。一緒に頑張りましょう。
では。