MENU

【初心者が挑戦】Flask入門:JavaScriptと連携しよう|変数の受け渡しやボタン配置

以前の記事で、「Pythonで簡単Webアプリ開発に挑戦」しました。基本的なことから初め、対話型アプリの作成やデータベースとの連携まで行いましたが、内容が多かったため、全体的に細かい説明が出来ませんでした。

そこで今回は、「JavaScriptと連携」部分に内容を絞って、丁寧に説明や解説をしていこうと思います。実際に私が学んだことや躓いたことについも、体験を踏まえながら紹介していきます。

私はJavaScriptが未経験だったため、同じようにPythonのみの知識があり、FlaskでWebアプリを作りたい思っている方には特に共感していただけると思います。もちろん、それ以外の方に対しても有用な記事になるようにまとめていますので、ご確認いただければと思います。

目次

はじめに:なぜFlaskアプリでJavaScriptが必要なのか

FlaskはPythonでWebアプリケーションを作るためのフレームワークです。主にサーバーサイド(Webサーバー側)で動作し、リクエストに応じてHTMLを生成したり、データベースと連携したりします。

一方、JavaScriptは主にクライアントサイド(ユーザーのWebブラウザ側)で動作するプログラミング言語です。HTMLと連携して、Webページに動きをつけたり、ユーザーの操作に応じて表示内容をリアルタイムに変更したりできます。

JavaScriptで出来ること
  • インタラクティブなUI: ボタンをクリックしたらメッセージを表示する、入力フォームの内容をチェックするなど、ユーザーの操作に即座に反応する動的なページを作れます。
  • 非同期通信: ページ全体を再読み込みせずに、サーバーから新しい情報を取得して画面の一部だけを更新できます。(例:チャット、新着情報の表示など)

JavaScriptをFlaskに組み込む基本

JavaScriptをFlaskテンプレート(HTMLファイル)で使う方法は主に2つあります。それぞれについて解説します。

<script>タグ内に直接書く方法(簡単なテスト向け)

HTMLファイルの中に<script>タグを書き、その中にJavaScriptコードを直接記述する方法です。

メリットは、ファイルが1つで済むため、少し動作を確認したいなどJSファイルを作るまでもないときに素早く確認出来ます。ただし、デメリットとしてHTMLコードがごちゃごちゃしてしまうので、基本的には使用しないほうが良いと感じました。(後から修正するのが大変です)

※HTMLとの見分けがつきにくくなるなど弊害があるため、基本的には次の方法を推奨します。

実際に例を見てみましょう。以下のコードをhtmlファイルとして保存し、ブラウザの上にドラッグ&ドロップすることで、動作を確認出来ます。やはり1ファイルで完結できる点はメリットですね。

<!DOCTYPE html>
<html>
<head>
    <title>テスト</title>
</head>
<body>
    <h1>JavaScriptテスト</h1>
    <button id="myButton">クリックしてね</button>

    <script>
        // この中にJavaScriptコードを書く
        console.log("JavaScriptが読み込まれました!");

        // ボタン要素を取得
        const button = document.getElementById('myButton');

        // ボタンがクリックされたときの処理を登録
        button.addEventListener('click', function() {
            alert('ボタンがクリックされました!');
        });
    </script>
</body>
</html>

外部ファイル(.js)を読み込む方法(推奨)

JavaScriptのコードが長くなるとHTMLが見づらくなるため、通常はこちらの方法を使います。ここで少しおさらいですが、FlaskではJavaScriptファイルはstaticというフォルダに保存するんでしたね。具体的に実施する内容は以下のとおりです。

実施内容
  1. staticフォルダの準備
    Flaskプロジェクト内にstaticという名前のフォルダを作成します。このフォルダは、CSS、JavaScript、画像など、Webページで使う静的ファイルを置くための特別なフォルダです。さらにその中にjsフォルダなどを作って整理するのが一般的なようです。(例: static/js/main.js
  2. JavaScriptファイルの作成
    static/js/フォルダ内にJavaScriptファイル(例: main.js)を作成し、コードを記述します。
  3. HTMLから読み込み
    HTMLファイルの<head>タグ内または<body>タグの最後で、<script>タグのsrc属性を使って外部ファイルを読み込みます。この際、Flaskのurl_for関数を使うのが一般的です。

まずはapp.pyを作り、FlaskのコードをPythonで書いていきます。
※Flaskの基本については、以前の記事で解説していますので、よければそちらをご確認下さい。

# app.py
from flask import Flask, render_template

app = Flask(__name__)

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

if __name__ == '__main__':
    app.run(debug=True)
render_template()について
  • render_templateは、FlaskでHTMLテンプレート(主にJinja2というテンプレートエンジンを使用)を使ってWebページを生成するための関数です。
  • render_template('表示するHTML'(index.htmlなど), 変数='◯◯'(name='太郎'など))という使い方をします。
  • 変数を引き継いだ場合、テンプレート内で{{ }}で囲うことで使用出来ます。(上の場合は{{ name }}と書けば「太郎」と表示されます。)
    ※詳しくは後ろの章で解説します。

次に、templatesというフォルダを作ってindex.htmlにHTMLを記述します。

<!DOCTYPE html>
<html>
<head>
    <title>外部JSテスト</title>
    </head>
<body>
    <h1>JavaScriptテスト</h1>
    <button id="myButton">クリックしてね</button>

    <script src="{{ url_for('static', filename='js/main.js') }}"></script>
</body>
</html>
{{ url_for('static', filename='js/main.js') }}について
  • {{ ... }}について
    • Flaskではテンプレートエンジン「Jinja2」が使われており、{{ ... }} の中に書いた式は、Flask側(サーバー側)で処理され、その結果だけがHTMLとして表示されます。
    • つまり、{{ ... }} を使うことで、テンプレート(HTML)の中で Python の値や式(関数の戻り値など)を埋め込むことが出来る。
  • url_for('static', filename='js/main.js')
    • Flaskのurl_for関数を使って、staticディレクトリ内のファイルのURLを動的に生成する関数です。

{{...}} の中で使える関数や変数はすべて「Flask(Python)側からテンプレートに渡したもの」や「Jinja2に用意されているもの」に限られます。

Flaskのテンプレートエンジン「Jinja2」を使うことで、他にもHTMLとの連携が楽になるものがあるようです!「Jinja2」については、また別の記事でまとめようと思いますので、そちらをご確認下さい。

最後に、main.jsというファイルを作ってJavaScriptを記入していきます。JavaScriptは少し細かく解説します。

// static/js/main.js
console.log("main.jsが読み込まれました!");

// ボタン要素を取得
// HTML要素が読み込まれた後に実行されるように、イベントリスナーを使うことが多い
document.addEventListener('DOMContentLoaded', function() {
    const button = document.getElementById('myButton');

    // ボタンが存在する場合のみ処理を実行(エラー防止)
    if (button) {
        // ボタンがクリックされたときの処理を登録
        button.addEventListener('click', function() {
            alert('外部ファイルからこんにちは!');
        });
    } else {
        console.error('ボタンが見つかりません。IDを確認してください。');
    }
});
コード解説
  • console.log("main.jsが読み込まれました!");
    • JavaScriptファイルが正常に読み込まれて実行されていることを確認するためのデバッグ用メッセージです。
    • ブラウザの開発者ツール(F12キーなどで開く)のコンソールに「main.jsが読み込まれました!」というメッセージが表示されます。
  • document.addEventListener('DOMContentLoaded', function() {
    • document は「今表示されているウェブページ全体」のことです。
    • .addEventListener('DOMContentLoaded', function() {…})は「ページのHTMLがすべて読み込まれたら実行してね」という意味です
    • たとえば、まだHTMLが全部読み込まれてないうちにボタンを探すと「見つからない!」というエラーになります。
  • const button = document.getElementById('myButton');
    • HTMLの中から id="myButton" という部分を探して、そのボタンの情報を取り出し、「button」という名前の変数に入れます。
  • button.addEventListener('click', function() {
    • addEventListener('click', ...)は、ボタンが「クリックされたときに何かするよ」と教えてる部分です。この中の function() { ... } に、「クリックされたら実行する内容」を書きます。

JavaScriptでHTMLを操作する(DOM操作の基礎)

JavaScriptがHTMLを操作する上で重要なのが DOM (Document Object Model) です。ブラウザはHTMLを読み込むと、それを木のような構造(DOMツリー)としてメモリ上に展開します。JavaScriptはこのDOMを操作することで、表示されているHTML要素を変更したり、新しい要素を追加したりできます。

基本のDOM操作

主なDOM操作としては、以下のものがあります。

要素の取得
  • document.getElementById('id名'): 指定したIDを持つ要素を取得します。(一番よく使います)
  • document.querySelector('セレクタ'): CSSセレクタに一致する最初の要素を取得します。(例: #myId, .myClass, div pなど)
  • document.querySelectorAll('セレクタ'): CSSセレクタに一致するすべての要素をリスト(NodeList)として取得します。
内容の変更
  • element.innerHTML = '新しいHTML': 要素内のHTMLを書き換えます。
  • element.textContent = '新しいテキスト': 要素内のテキストだけを書き換えます。(innerHTMLより安全な場合が多いようです)
属性の変更
  • element.setAttribute('属性名', '値'): 要素の属性を設定・変更します。
    (例: imgElement.setAttribute('src', 'new_image.jpg')
  • element.getAttribute('属性名'): 属性の値を取得します。
  • element.style.プロパティ名 = '値': CSSスタイルを変更します。
    (例: element.style.color = 'red'
イベント処理
  • element.addEventListener('イベント名', 関数): 要素に対して特定のイベント(クリック、マウスオーバー、キー入力など)が発生したときに実行される処理(関数)を登録します。

DOM操作で入力内容をリアルタイムに表示する

上で学んだ内容を使って、テキストボックスに入力した内容が、リアルタイムで別の場所に表示される機能を実装してみようと思います。

手順1:templates/index.htmlの変更

入力フィールド (<input type="text">) と、入力内容を表示するための <span> タグを追加します。<span> タグにはIDを付けて、JavaScriptから特定できるようにしておきます。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>実践演習</title>
</head>
<body>
    <h1>入力内容をリアルタイム表示</h1>

    <label for="myInput">入力してください:</label>
    <input type="text" id="myInput">

    <p>入力された内容: <span id="outputArea">ここに表示されます</span></p>

    <script src="{{ url_for('static', filename='js/main.js') }}"></script>
</body>
</html>

手順2:static/js/main.jsの変更

入力フィールドと表示エリアの要素を取得し、入力フィールドで input イベントが発生するたびに、入力された値を取得して表示エリアのテキストを更新する処理を追加します。

console.log("演習のJavaScriptが読み込まれました。");

document.addEventListener('DOMContentLoaded', function() {
    const inputField = document.getElementById('myInput');
    const outputArea = document.getElementById('outputArea');

    // inputField と outputArea が両方存在する場合のみ処理
    if (inputField && outputArea) {
        // inputイベントリスナーを追加
        // 'input'イベントは、入力フィールドの値が変わるたびに発生する
        inputField.addEventListener('input', function() {
            // inputFieldの現在の値を取得 (.value)
            const inputValue = inputField.value;
            // outputAreaのテキスト内容を更新 (.textContent)
            outputArea.textContent = inputValue;
        });
    } else {
        console.error('入力フィールドまたは出力エリアが見つかりません。IDを確認してください。');
    }
});

プログラムの動作確認

python app.pyでFlaskアプリを実行し、ブラウザで http://127.0.0.1:5000/ にアクセスします。テキストボックスに何か入力してみてください。入力した文字がリアルタイムで下の <span> タグの場所に表示されれば成功です!

実行した結果は上のとおりです。実際に自分で操作してみてください。「入力してください」の横に入力した文字が、リアルタイムに下に反映されることが確認出来ると思います。

FlaskからJavaScriptへデータを渡す

Flask(Python)側で持っているデータを、JavaScriptで利用したい場合があります。例えば、ユーザー名をページに表示したり、グラフの初期データを設定したりする場合です。

render_templateを使った変数の受け渡し(PythonとHTML)

render_template 関数を使う際に、Pythonの変数をHTMLテンプレートに渡すことができます。そして、その値をJavaScriptの変数に埋め込むことができます。具体的な手順は以下のとおりです。

手順1:Flask (app.py) でデータを渡す

render_template の引数として、変数名=値 の形で渡します。render_template('HTML名', 変数名=値)

from flask import Flask, render_template, jsonify # jsonifyを追加
import json # jsonモジュールをインポート

app = Flask(__name__)

@app.route('/')
def index():
    user_name = "ゲスト" # 例: ログイン機能があれば実際のユーザー名
    initial_data = {'item': 'リンゴ', 'price': 150}
    message_list = ["メッセージ1", "メッセージ2", "重要なお知らせ"]

    return render_template(
        'index.html',
        username=user_name,
        initial_item_data=initial_data, # 辞書データ
        messages=message_list # リストデータ
    )

if __name__ == '__main__':
    app.run(debug=True)

手順2:HTMLテンプレート (index.html) で受け取り、JavaScript変数に入れる

テンプレートエンジン (Jinja2) の {{ }} を使ってPythonの変数を展開し、JavaScriptの変数に代入します。

変数展開時の注意点
  • 文字列
    そのまま {{ 変数名 }} で展開できますが、JavaScriptの文字列として扱うにはクォーテーション (' '" ") で囲む必要があります。
  • 数値
    そのまま {{ 変数名 }} で展開できます。
  • リストや辞書 (複雑なデータ)
    JSON形式に変換して渡すのが安全で確実です。Flaskの tojson フィルターを使います。
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Flaskからデータ受け渡し</title>
</head>
<body>
    <h1>ようこそ、<span id="usernameDisplay"></span> さん!</h1>
    <p>初期アイテム: <span id="itemDisplay"></span></p>
    <p>メッセージ一覧:</p>
    <ul id="messageList"></ul>

    <script>
        // 文字列: クォーテーションで囲む
        const currentUsername = '{{ username }}';

        // 辞書やリスト: tojsonフィルターを使う (安全)
        // | safe フィルターは、JSON文字列がHTMLエスケープされるのを防ぐ
        const initialItem = JSON.parse('{{ initial_item_data | tojson | safe }}');
        const messageArray = JSON.parse('{{ messages | tojson | safe }}');

        console.log("ユーザー名:", currentUsername);
        console.log("初期アイテム:", initialItem);
        console.log("メッセージ:", messageArray);
    </script>

    <script src="{{ url_for('static', filename='js/main.js') }}"></script>
</body>
</html>

プログラムを実行すると、以下のようにブラウザの開発者ツール(F12キーなどで開く)のコンソールに「ユーザー名」、「初期アイテム」、「メッセージ」が表示されます。
※この時点では、HTMLを書き換えていないためサイトは変化しません。HTMLへの反映は次の章のJavaScriptで実施します。

コード解説
  • <span id="usernameDisplay"></span>
    • ユーザー名を表示するための空の要素です。
    • JavaScriptで後から内容を設定します。
  • {{ }}
    • Flaskのテンプレートエンジン(Jinja2)の記法で、Pythonから渡された変数がここに挿入されます。
  • JSON.parse()
    • 文字列をJavaScriptのオブジェクト(辞書やリスト)に変換する関数です 。
  • {{ initial_item_data | tojson | safe }}
    • initial_item_data: Pythonから渡される変数名
    • tojson: PythonのデータをJSON形式に変換するフィルター
    • safe: HTMLエスケープを防止するフラグ(特殊文字が変換されないようにする)

注意点 :セキュリティについて

ユーザーが入力した内容などをそのままJavaScriptコード内に埋め込むと、クロスサイトスクリプティング (XSS) と呼ばれる脆弱性につながる可能性があります。悪意のあるスクリプトが埋め込まれて実行されてしまう危険性です。そのため、以下のようにします。

  • tojson フィルターは、データを安全なJSON文字列に変換してくれるため、XSS対策としても有効です。
  • safe フィルターは tojson と一緒に使うことが多いです。JSON.parse する際にHTMLエスケープが問題になる場合に safe を追加します。

ここまでの内容を学んできて、基本的にHTMLとJavaScriptは分けたほうが良いのに、今回はHTMLの中にJavaScriptを書いたことに違和感を感じました

調べてみたところ、Flaskの変数を直接JavaScriptで直接読み込むことは出来ず、HTMLファイル内でデータを一旦グローバル変数に格納する必要があるようです。

Flaskから渡されたデータを画面に表示(JavaScript)

Flaskから渡されたデータをJavaScriptを使ってHTMLに反映し、画面に表示させようと思います。実施手順は以下の通りですが、手順1と手順2は既に前章で行っているため、実際は手順3のみで大丈夫です。

実施手順
  1. app.py の変更
    render_templateを使ってデータ渡しを行います。(実施済み)
  2. templates/index.html の変更
    <script> タグでのデータ受け取り部分と、表示用のHTML要素 (span, ul) を準備します。(実施済み)
  3. static/js/main.js の変更
    ページ読み込み時 (DOMContentLoaded) に、HTML内で定義されたJavaScript変数 (currentUsername, initialItem, messageArray) を使って、対応するHTML要素の内容を書き換える処理を追加します。
console.log("演習2のJavaScriptが読み込まれました。");

document.addEventListener('DOMContentLoaded', function() {
    const usernameDisplay = document.getElementById('usernameDisplay');
    const itemDisplay = document.getElementById('itemDisplay');
    const messageListUl = document.getElementById('messageList');

    // グローバルスコープの変数(HTML内で定義したもの)にアクセス
    // 変数が存在するかチェックするとより安全
    if (typeof currentUsername !== 'undefined' && usernameDisplay) {
        usernameDisplay.textContent = currentUsername;
    }

    if (typeof initialItem !== 'undefined' && itemDisplay) {
        // オブジェクトのプロパティにアクセス
        itemDisplay.textContent = `${initialItem.item} (${initialItem.price}円)`;
    }

    if (typeof messageArray !== 'undefined' && messageListUl) {
        // 配列の各要素に対して処理 (forEach)
        messageArray.forEach(function(message) {
            // 新しい<li>要素を作成
            const listItem = document.createElement('li');
            // <li>要素のテキストを設定
            listItem.textContent = message;
            // <ul>要素に<li>要素を追加
            messageListUl.appendChild(listItem);
        });
    }
});

上記のようにJavaScriptを作成し、Flaskを実行することで、以下のように画面に表示することが出来ました。

コード解説

条件分岐if (typeof currentUsername !== 'undefined' && usernameDisplay)

  • typeof は変数の型(種類)を調べる演算子です 。
  • currentUsernameという変数が宣言されているかをチェックしています 。
  • !== は「等しくない」という比較演算子です つまり「currentUsernameが未定義ではない」という条件です。
  • (&&)は「かつ」という扱いで、どちらの条件も満たす場合という意味になります。
  • usernameDisplay:JavaScriptでは、値があればそれは「真(true)」と評価されまが、値がない(nullundefined)場合は「偽(false)」と評価されます。

HTMLの変更itemDisplay.textContent = `${initialItem.item} (${initialItem.price}円)`;

  • itemDisplay.textContent はHTML要素のテキスト内容を設定するプロパティです。
  • バッククォート(`)で囲まれた部分はテンプレートリテラルと呼ばれる文字列表現方法です。
  • テンプレートリテラルで${...}を使うことで、変数の値を文字列に埋め込みます。
  • initialItem.item は initialItem オブジェクトの item プロパティ(商品名)を取得しています。

繰り返し処理messageArray.forEach(function(message) { // 処理内容 });

  • forEach は配列のメソッド(関数)で、配列の各要素に対して同じ処理を繰り返し適用します。
  • function(message) { ... } はコールバック関数と呼ばれ、各要素に対して実行される処理を定義します。
  • message は現在処理中の配列要素が入る変数です。(自動的に設定されます)

リストへの記入(画面表示)

  • document.createElement('li') は新しいHTML要素(リストアイテム)を作成します。
  • const listItem = でその新しい要素を変数に保存しています。
  • listItem.textContent = message;で、作成したリスト項目のテキスト内容を、現在処理中のメッセージに設定します。
  • appendChild() は親要素に子要素を追加するメソッドで、作成・設定したリスト項目を、実際にULリスト要素に追加します。

ボタン操作の導入:非同期通信 (Fetch API)

これまでは、ページが表示されるときにFlaskから渡されたデータを使っていました。しかし、「ボタンを押したら新しいデータをサーバーに問い合わせて表示する」のように、ページを表示した後にサーバーと通信したい場合がありますよね?

これを実現するのが 非同期通信 というものです。ページ全体を再読み込みせずに、JavaScriptが裏側でサーバーとデータのやり取りをする操作のことです。

現代のJavaScriptで非同期通信を行う標準的な方法は Fetch API というもので、これを実装してみようと思います。具体的には、Fetch APIを使って、ボタンをクリックするとFlaskサーバーから動的にデータを取得し、その結果をWebページに表示する機能を実装してみます。

基本的な処理の流れ
  1. ユーザーがボタンをクリック
    • ウェブページ上の「データ取得ボタン」がクリックされます。
  2. クライアント側の準備
    • JavaScriptが「データ取得中…」という表示に更新します。
    • サーバーへのリクエストを準備します。
  3. サーバーへのリクエスト送信
    • JavaScriptのfetch関数が/api/dataというURLにリクエストを送ります。
  4. サーバー側で処理
    • Flaskサーバーがリクエストを受け取ります。
    • ランダムな数値(1〜100)を生成します。
    • 数値とステータス情報をJSON形式のデータにまとめます。
  5. サーバーからの応答
    • サーバーがJSON形式のデータをクライアントに返送します。
  6. クライアント側でデータを処理
    • JavaScriptがサーバーからのデータを受け取ります。
    • 受け取ったデータから必要な情報を取り出します。
  7. 画面の更新
    • 「取得した値: X, ステータス: OK」という形式で画面表示を更新します。

手順1:app.py の変更

まずはapp.pyjsonify を使ってJSONを返すルートを追加します。(/api/data エンドポイントを追加)

from flask import Flask, render_template, jsonify
import json
import random
from datetime import datetime # datetimeをインポート

app = Flask(__name__)

@app.route('/')
def index():
    # ... (演習2のデータ渡しコード) ...
    return render_template(
        'index.html',
        # ... (演習2の引数) ...
    )

@app.route('/api/data')
def get_data():
    random_value = random.randint(1, 100)
    server_data = {'value': random_value, 'status': 'OK', 'timestamp': datetime.now().isoformat()}
    print(f"APIリクエスト受信: {server_data}")
    return jsonify(server_data)

if __name__ == '__main__':
    app.run(debug=True)
コード解説

jsonify()の効果

  • データ変換: Pythonの辞書(dictionary)やリストなどのデータ構造をJSON文字列に変換します。
  • HTTPレスポンスの作成: 単にJSON文字列を作るだけでなく、以下の処理も行います。
    (ここは内容が少し難しいため、スルーしても問題ないと思います。)
    • 適切な「Content-Type: application/json」ヘッダーを設定
    • 正しいHTTPステータスコード(デフォルトでは200 OK)を設定
    • 文字エンコーディングの設定
  • ブラウザ対応: クライアント側(ブラウザのJavaScript)が直接扱えるレスポンスを生成します。

手順2:templates/index.html の変更

データ取得用のボタンと、取得したデータを表示するためのエリア(例: <p>タグ)を追加します。

<!DOCTYPE html>
<html lang="ja">
<body>
    <hr> <h2>非同期データ取得 (Fetch API)</h2>
    <button id="fetchDataButton">サーバーからデータを取得</button>
    <p id="dataDisplay">ここに取得結果が表示されます</p>

    <script src="{{ url_for('static', filename='js/main.js') }}"></script>
</body>
</html>

手順3:static/js/main.js の変更

Fetch APIを使ってデータを取得し、表示を更新するコードを追加します。

document.addEventListener('DOMContentLoaded', function() {
    const fetchButton = document.getElementById('fetchDataButton');
    const dataDisplayArea = document.getElementById('dataDisplay');

    if (fetchButton && dataDisplayArea) {
        fetchButton.addEventListener('click', function() {
            dataDisplayArea.textContent = 'データ取得中...'; // ローディング表示

            fetch('/api/data') // FlaskのAPIエンドポイントを呼び出す
                .then(response => {
                    if (!response.ok) {
                        // okプロパティはステータスコードが200-299の範囲ならtrue
                        throw new Error('ネットワークレスポンスエラー Status: ' + response.status);
                    }
                    return response.json(); // JSONに変換するPromiseを返す
                })
                .then(data => {
                    // JSONデータの取得成功
                    console.log('サーバーから受信:', data);
                    const displayTime = new Date(data.timestamp).toLocaleString('ja-JP'); // 見やすい形式に
                    dataDisplayArea.textContent = `取得値: ${data.value} (ステータス: ${data.status}, 取得時刻: ${displayTime})`;
                })
                .catch(error => {
                    // エラーハンドリング
                    console.error('Fetch処理中にエラーが発生しました:', error);
                    dataDisplayArea.textContent = 'データの取得に失敗しました。コンソールを確認してください。';
                });
        });
    } else {
        console.error('データ取得ボタンまたは表示エリアが見つかりません。IDを確認してください。');
    }
});
コード解説

fetch('/api/data')

  • サーバーの「/api/data」というURLからデータを取得する処理を開始します。
  • fetchは非同期処理なので、データが取得できるまで次の処理を待たずに進めることができます。

.then()

  • .then()は、JavaScriptで非同期処理(時間がかかる処理)を扱うときに使うPromiseという機能の一部です。
  • 簡単に言うと「この処理が終わったら、次にこれをやってね」と指示するための方法です。
  • 例えば、サーバーからデータを取得してからそのデータを画面に表示したいときや、一つの処理が終わってから、次の処理を行いたいときに使います。

response => { ... }

  • response => はアロー関数(Arrow Function)の一部で、関数の短縮記法です。
  • function(response) { // 処理 }と同じ意味になります。
  • responseはPromiseから渡される値を受け取るための変数名で、好きな文字で設定出来ます。

new Date(…)

  • new は 新しいオブジェクトを作るために使うキーワードです。
  • new Date(...) とすることで、 日時を扱うための特別なオブジェクトを作る事ができます。

Flask側でjsonify()を使っているのに、なぜresponse.json()が必要?

  • Flask から送られてきたデータは、HTTPレスポンスとして送られます
  • これは中身がJSONであっても、文字列として届くんです。
  • そのため、受け取った文字列のJSONデータをJavaScriptが扱える「オブジェクト」に変換する必要があります!

処理の流れ(例)

Flask側の処理:return jsonify({‘value’: 42})
→ブラウザ側の受け取り:'{“value”: 42}’
→JavaScript 側での変換:{ value: 42 }(response.json()による変換)

実際にプログラムを実行し、「サーバーからデータを取得」ボタンをクリックしてみましょう。「データ取得中…」と表示された後、サーバーから取得したランダムな値とステータス、取得時刻が表示されれば成功です!ボタンを何度か押すと、表示される値が変わるはずです。Flaskを実行しているターミナルのログにも /api/data へのアクセス記録が表示されます。

ちなみに、どこかで間違っている場合は以下のようにエラーが表示されます。(私は、randomとdatetimeのインポートを忘れており、最初にエラーが出ました。)

まとめ

今回は、FlaskアプリケーションでJavaScriptを使うための基本的な方法について学びました。主に以下のような内容でしたね。

学んだこと
  • static フォルダと url_for を使ってJavaScriptファイルを読み込む方法
  • 基本的なDOM操作(要素の取得、内容変更、イベントリスナー)
  • FlaskからJavaScriptへデータを渡す方法(render_templatetojson フィルター)
  • Fetch APIを使った非同期通信で、Flaskサーバーと動的にデータをやり取りする方法

今回の内容がわかれば、以前紹介したWebアプリの記事もより理解が進むと思います。良ければそちらも御覧ください。

では、また学習した内容を随時紹介していきますので、良ければ他の記事もご覧ください!

よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

非IT職のデスクワーカーです。
簡単な業務効率化やデータ分析にPythonをよく活用しています。
このブログを通してAI技術を身に着け、より業務効率化や新しいものを作りたいと考えています。

目次