気ままに趣味旅行

面白いコト「拡がる/拡げる」

WEBアプリケーションを作る4ーFlask編ーくじ引きアプリ、WEBの基礎について

どうもhiroakiです。

 

前回に引き続き、Flaskを使ったWEBアプリケーションを作る方法を紹介します。読まれてない人は前回の記事もご参考ください。HTMLとCSSについては以下を参考ください。

 

WEBの基礎

WEBで特に押さえるべきはHTML、HTTP、URLの3つです。HTMLについては前回の記事を読まれている人なら、もう大丈夫ですね。心配な人は戻って読まれることをおすすめします。

ではまず、HTTPについて説明していきます。ちなみに前回、「WEBの世界はシンプルです」とお伝えしましたが、覚えていますか。

クライアント(client)がリクエスト(Request)を投げ、サーバー(Server)がレスポンス(Response)を返します。

まだ、覚えてないという人はしっかり覚えてくださいね。実は、上記が成立するためには、HTTPが必要になります。HTTP(HyperText Transfer Protocol)とは「HyperText」のデータをやり取りするためのプロトコル(決まりごと)と理解してください。英語部分を読んでもらえれば、そのままの意味になっていますね。

HTTPでのデータ送受信は、クライアントとWebサーバーの間で行われます。クライアントは「HTTPリクエスト」をWebサーバーに送信し、サーバーはそのリクエストを処理して「HTTPレスポンス」をクライアントに返却します。

代表的なクライアントは、ブラウザーです。ブラウザーはHTTPに乗っ取ってデータの送受信をしWebページを表示しています。大まかにいうと、ブラウザーは下記の順序でWebサーバーとデータをやりとりします。

  1. ブラウザーはHTTPリクエストのメッセージを組み立てる
  2. ブラウザーはURL(Webサーバー)に対してHTTPリクエストを送信する
  3. WebサーバーはHTTPリクエストを解析する
  4. Webサーバーはリクエストの内容に応じたHTTPレスポンスを組み立てる
  5. WebサーバーはHTTPレスポンスをブラウザーに返却する
  6. ブラウザーは受け取ったHTTPレスポンスを解析する
  7. ブラウザーは解析した内容を画面に表示する(HTMLであればレンダリングrenderして表示する)

「HTTPリクエスト」は単純にコンテンツを取得する以外の方法も提供します。その方法のことを「HTTPメソッド」と呼びます。主なメソッドは以下の通りです。

GET...Webサーバーに対してヘッダーとコンテンツ双方をリクエス

POST...Webサーバーに対して新しいデータを送信

HEAD ... Webサーバーに対してヘッダーのみを要求

PUT ... Webサーバーにある既存のデータを更新する

DELETE ... Webサーバーにある既存のデータを削除する

 
次にURLについて説明します。
URL(Uniform Resource Locator)は、WEB上でコンテンツを識別するための識別子です。住所のようなものと理解してください。これのおかげで世界中のWEBコンテンツを一意に特定できます。
例えば、下をみてください。 このURLの意味を説明していきます。

「http://」の部分をスキーマと呼びます。データをやり取りするための手段だとイメージしてください。httpとなっているので、上記で説明したHTTPでデータをやりとりするという意味です。ちなみに、http以外にもftpやmailto、fileなどさまざまなデータに合わせたスキーマが存在します。

「www.google.co.jp」はホスト名です。ホストとは、そのコンテンツを管理するサーバなどを指します。ホスト名は「ドメイン」や「IPアドレス」などで表現されます。

「/search?q=Python」は具体的なコンテンツの名前です。ホスト内部でのファイルパスを示します。

このように、ブラウザーはURLのおかげで、「どういう手段」で「どのホスト」の「どのコンテンツ」を表示するか判別できるのです。
 

参考文献:
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に以下のコードを作ります。

  1. from flask import Flask, redirect,render_template,
  2. request,url_for
  3. app = Flask(__name__)
  4. @app.route("/")
  5. def index():
  6.      return render_template('input.html')
  7. @app.route("/output", methods=['POST'])
  8. def output():
  9.     your_name = request.form['name']
  10.     return redirect(url_for('redirect_test',name=your_name))
  11. @app.route("/redirect_test",methods=['GET'])
  12. def redirect_test():
  13.     your_name=request.args.get('name','')
  14.     return render_template('output.html', name=your_name)

これ見てもらうと分かる通り、postで受け取ったnameの値をgetで受け直してるんですね。そうすることで、二重送信問題を回避しています。このときユーザーには/から/redirect_testに直接移動したように見えますが、実際には/と/redirect_testの間には/outputというURLがあり、そこを介して遷移していることになります。

 

 

今回は以上です。何度も繰り返して理解しましょう。

皆さんの疑問を、ちょっとずつ紐解いていけてると嬉しいです。次回も続きをやっていきますので、不明点等ありましたら、気軽にコメントください。一緒に頑張りましょう。

 

では。