【Laravel】Ajaxを使った非同期通信の実装例|バリデーションやデータ保存をリアルタイムに

【Laravel】Ajaxを使った非同期通信の実装例|バリデーションやデータ保存をリアルタイムに Laravel

Laravelでは、JavaScriptと組み合わせることでAjax(非同期通信)を簡単に実装できます。ページのリロードなしでバリデーションやデータの送受信を行いたい場合に非常に有効です。この記事では、LaravelとjQueryを使ったAjax通信の基本から、バリデーション・データ保存・レスポンス処理まで、実践的な実装例を紹介します。

前提:フォームを非同期で処理したいケース

以下のような「名前」と「メールアドレス」を送信するフォームを非同期で処理することを例に進めます。

1. フロント側フォームとAjax処理

まずはHTMLのフォームとjQueryによるAjax送信処理を準備します。

<form id="ajax-form">
  <input type="text" name="name" placeholder="お名前">
  <input type="email" name="email" placeholder="メールアドレス">
  <button type="submit">送信</button>
</form>

<div id="message"></div>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
  $('#ajax-form').on('submit', function (e) {
    e.preventDefault();

    $.ajax({
      url: '/ajax-submit',
      type: 'POST',
      data: {
        name: $('input[name="name"]').val(),
        email: $('input[name="email"]').val(),
        _token: '{{ csrf_token() }}'
      },
      success: function (response) {
        $('#message').html('<p>' + response.message + '</p>');
      },
      error: function (xhr) {
        const errors = xhr.responseJSON.errors;
        let html = '<ul>';
        for (let key in errors) {
          html += '<li>' + errors[key][0] + '</li>';
        }
        html += '</ul>';
        $('#message').html(html);
      }
    });
  });
</script>

2. ルートの定義

Laravelのroutes/web.phpに以下のルートを追加します。

use App\Http\Controllers\AjaxFormController;

Route::post('/ajax-submit', [AjaxFormController::class, 'submit']);

3. コントローラの作成とバリデーション

フォーム送信先となるコントローラを作成します。

php artisan make:controller AjaxFormController

以下のように、バリデーションとJSONレスポンスを実装します。

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class AjaxFormController extends Controller
{
    public function submit(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name'  => 'required|string|max:50',
            'email' => 'required|email|max:100',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'errors' => $validator->errors()
            ], 422);
        }

        // 保存処理(例:DB保存など)
        // User::create($request->only('name', 'email'));

        return response()->json([
            'message' => '送信が完了しました!'
        ]);
    }
}

4. CSRFトークンの注意点

LaravelはCSRF対策が有効なので、AjaxでPOSTリクエストを送る際は_tokenを必ず含める必要があります。Bladeテンプレート内で{{ csrf_token() }}をJavaScriptに渡すか、metaタグを使って一括設定も可能です。

<meta name="csrf-token" content="{{ csrf_token() }}">

<script>
  $.ajaxSetup({
    headers: {
      'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
  });
</script>

5. バリデーションエラーの表示

バリデーションに失敗した場合、ステータスコード422でエラーメッセージが返ってきます。AjaxのerrorコールバックでresponseJSON.errorsを使って表示することで、リアルタイムなフィードバックが可能です。

まとめ

LaravelとjQueryを組み合わせることで、フォーム送信時のページリロードを避けたスムーズなユーザー体験が実現できます。バリデーションやエラーハンドリングもサーバーサイドでしっかり管理しつつ、非同期通信によってインタラクティブな処理が可能になります。

今回の例をベースに、リアルタイム検索やオートコンプリート、ファイルアップロードなども拡張可能です。