Flaskで作るSNS　Flask(Ajax)編

#TL;DL

Udemyの下記講座の受講記録

Python+FlaskでのWebアプリケーション開発講座！！～0からFlaskをマスターしてSNSを作成する～
https://www.udemy.com/course/flaskpythonweb/

この記事ではAjaxによる非同期通信について記載する。

##Ajaxとは
・Ajax(Asynchronous JavaScript and XML)とは、HTML、CSS、Javascriptなどの複合技術である。ウェブアプリケーションにおいてより早くページを表示すること、ページの全体を再読み込みすることなくインターフェースを部分部分で更新することが可能となる。
→画面遷移せずにページのコンテンツを更新したい場合に利用する。

＜公式＞
https://flask.palletsprojects.com/en/1.1.x/patterns/jquery/

・jQueryを使用するために、googleのCDNを利用する。
**Ajax API**
https://developers.google.com/speed/libraries

**3.x snippet:**

```javascript
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
```

##コードサンプル

構成
sample
├── app.py
└── templates
　　　└── index.html

**app.py**

```python
from flask import Flask, request, render_template, jsonify

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/_add_numbers')
def add_numbers():

    # request.args.get(クエリパラメータ、[デフォルト値]、[値の型])
    a = request.args.get('a', 0, type=int)
    b = request.args.get('b', 0, type=int)

    # jsonify({key:value}): 引数に与えられた辞書形式データをJsonに変換する。
    # またその際にheaderの"content-type"を'application/json'に変換してくれる。
    return jsonify({'result': a+b})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)
```

**index.html**

```html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
    $(function(){
        $('a#calculate').bind('click', function(){
            $.getJSON('/_add_numbers', {
                a: $('input[name="a"]').val(),
                b: $('input[name="b"]').val()
            }, function(data){
                $("#result").text(data.result)
            });
        });
    });

</script>
<h1>Jquery Sample</h1>
<p>
    <input type="text" size=5 name='a'>+
    <input type="text" size=5 name='b'>=
    <span id='result'>?</span>
</p>
<a href="#" id='calculate'>Calculate</a>
```

### 処理の流れ
１． app.pyのルートディレクトリの処理を実行し、index.htmlを画面表示する。
２． 「calculate」リンクを押下すると、clickイベントに反応してgeJSON処理を実行する。
getJSON処理でフィールドa、bから入力値を取得し、「app.py」で定義している「/_add_numbers」ルートの処理を実行する。（=イベント処理）
３． add_numbers処理では、requestでクエリパラメータからa、bの値を取得し、jsonifyモジュールを利用してJSON形式で結果をindex.htmlに返す。
４． イベント処理の結果をgetJSON()の第三引数であるイベントハンドラーに渡す。（"function(data)"のdata）
５． add_numbersから受け取った結果をid=resultのタグのテキストに反映する。


**画面イメージ**
![スクリーンショット 2021-01-17 14.07.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600163/a749d80c-1b4c-33c5-6db1-80b82393f6ee.png)


![スクリーンショット 2021-01-17 14.07.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600163/d0256194-9bf8-a61e-ffca-ba4770c45841.png)


###JQueryのメソッド


参考：
http://semooh.jp/jquery/

```javascript
$('HTML要素').bind( eventType [, eventData], handler(eventObject) ) 
```
| 内容 | 説明 |
|:-:|:--|
| .bind() | HTML要素に以降の処理を紐付ける  |
| eventType  | 処理を起動するキーとなるDOMイベント。カンマ区切りで複数指定可能。'click''submit'など  |
| eventData  | 任意。eventHandlerに渡すデータを定義可能。（関数OK）  |
| handler(eventObject) | eventTypeに低付議しているイベントが発生した場合に実行する処理を定義する。eventDataを定義している場合、handlerの引数として受け取ることが可能。(引数に使用する名称は任意)  |


```javascript
$.getJSON( url [, data] [, success(data, textStatus, jqXHR)] )
```

| 内容 | 説明 |
|:-:|:-- |
| url | リクエスト送信先URLを指定する。 |
| data | サーバーに送信するデータを指定する。サーバーに送信する前にURLエンコードが施される。 |
| callback | リクエストの送信が成功した場合に実行されるコールバック関数。リクエスト送信先URLからreturnされた値を関数の引数として受け取ることができる。