Flaskでフォームを送信せずに部分更新する方法を解説!初心者でもわかるDOM更新と非同期通信
生徒
「先生、Flaskでフォームを送信したらページが全部リロードされるんですけど、送信せずに一部分だけ更新することってできますか?」
先生
「とても良いところに気づきましたね。Flaskでは、JavaScriptと連携することでページ全体をリロードせず、必要な部分だけを更新することができますよ。」
生徒
「どうやってそんなことができるんですか?」
先生
「それには『非同期通信(ひどうきつうしん)』という仕組みを使います。英語では “AJAX” や “Fetch API” と呼ばれるものです。フォームを送信せずに、サーバーとデータをやり取りして、画面の一部分だけを更新する方法を一緒に学んでいきましょう。」
1. Flaskとフロントエンドの部分更新とは?
通常、Flask(フラスク)でフォームを送信すると、ブラウザ全体がリロードされて、サーバーから新しいHTMLページが再表示されます。ですが、ユーザーにとっては画面がチカチカして見にくく、操作も遅く感じてしまいます。
そこで登場するのが「非同期通信」と「DOM(ドム)更新」です。DOMとは、ブラウザがページを理解するために作る“ページの構造のデータ”のことです。これをJavaScriptで直接書き換えることで、ページを丸ごと再読み込みしなくても部分的に更新できるのです。
たとえば、コメント欄に「送信」ボタンを押したら、ページ全体を再読み込みせずにコメントだけを追加することができます。これが「部分更新」です。
2. Flask側(サーバー側)の準備
まずはFlaskのサーバー側で、フォームから送られてくるデータを受け取り、結果をJSON形式(データをテキストで表現する軽量なフォーマット)で返すようにします。
from flask import Flask, request, jsonify, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/add_comment', methods=['POST'])
def add_comment():
data = request.get_json()
comment = data.get('comment')
new_comment = f"あなたのコメント: {comment}"
return jsonify({'comment': new_comment})
ここではrequest.get_json()を使って、JavaScriptから送られてくるJSONデータを受け取ります。そして、返すときもjsonify()でJSONとして返しています。これにより、ブラウザ側で受け取ったデータを使って動的にDOMを更新できるようになります。
3. フロントエンド側(HTML+JavaScript)の作成
次に、フォームを送信せずにFlaskと通信するHTMLとJavaScriptを作りましょう。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Flask 部分更新の例</title>
</head>
<body class="container py-4">
<h2>コメントを追加</h2>
<form id="commentForm">
<input type="text" id="commentInput" placeholder="コメントを入力" class="form-control mb-2">
<button type="submit" class="btn btn-primary">送信</button>
</form>
<h3 class="mt-4">コメント一覧</h3>
<div id="commentList"></div>
<script>
const form = document.getElementById("commentForm");
const input = document.getElementById("commentInput");
const list = document.getElementById("commentList");
form.addEventListener("submit", async function(e) {
e.preventDefault(); // ページの再読み込みを止める
const commentText = input.value;
const response = await fetch("/add_comment", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ comment: commentText })
});
const data = await response.json();
const newDiv = document.createElement("div");
newDiv.textContent = data.comment;
list.appendChild(newDiv);
input.value = ""; // 入力欄をリセット
});
</script>
</body>
</html>
このコードでは、フォームを送信してもページ全体をリロードしません。代わりにJavaScriptのfetch()を使ってFlaskにデータを送信し、結果を受け取ってDOMを直接更新しています。
appendChild()は、HTMLの要素を追加するための関数です。新しいコメントを受け取るたびに、コメント一覧に追加されていく仕組みになっています。
4. 部分更新の流れを理解しよう
ここまでをまとめると、FlaskとJavaScriptの連携による「部分更新(DOM操作)」の流れは次の通りです。
- ユーザーがコメントを入力して送信ボタンを押す。
- JavaScriptがフォームのデータをFlaskにJSON形式で送る(fetch関数)。
- Flaskが受け取って処理し、結果をJSONで返す。
- JavaScriptが返ってきたデータを読み取り、HTMLの一部(DOM)を書き換える。
このように「ページ全体をリロードしないでデータを更新する仕組み」は、今のWebアプリケーションの基本です。TwitterやInstagramなども同じ仕組みで動いており、画面の一部だけをスムーズに変えています。
5. エラー処理も加えてみよう
実際のアプリでは、通信に失敗した場合や、サーバーでエラーが起きた場合もあります。そのため、エラーが出たときの処理も書いておくとより安定したアプリになります。
<script>
form.addEventListener("submit", async function(e) {
e.preventDefault();
const commentText = input.value.trim();
if (!commentText) {
alert("コメントを入力してください。");
return;
}
try {
const response = await fetch("/add_comment", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ comment: commentText })
});
if (!response.ok) {
throw new Error("通信エラーが発生しました。");
}
const data = await response.json();
const newDiv = document.createElement("div");
newDiv.textContent = data.comment;
list.appendChild(newDiv);
input.value = "";
} catch (error) {
alert(error.message);
}
});
</script>
このようにtry...catch構文を使うことで、通信中に問題が起きてもユーザーに分かりやすくエラーメッセージを出すことができます。
6. 実際の動作イメージ
これを実行すると、コメントを入力して「送信」ボタンを押した瞬間に、ページ全体をリロードせずにコメントが下に追加されます。FlaskとJavaScriptの連携によって、スムーズでストレスのないユーザー体験を作ることができるのです。
このような技術は「シングルページアプリケーション(SPA)」の基礎でもあり、Flaskを使ったフロントエンド連携の第一歩となります。