🛒👉🏻Amazonブラックフライデー開催中!!👈🏻🛒

Laravelでブラウザのリロード(再読み込み)を判定する

Laravel Laravel

Laravelでブラウザのリロード(再読み込み)を判定する

Laravelで、リロードの判定をする必要があったので、セッションを使ってやってみました。

初期表示の画面でボタンを押されたときにGetリクエストで何かの処理をして、初期表示のメソッドにリダイレクトする。といった構成のコントローラーです。
この記事ではリロードの判定の対応方法をコードを載せて解説しています。

セッションの情報はブラウザを閉じるまで残るので、初期表示の判定は初めの一回だけです。
厳密には「URLを叩いた時の初期表示またはリロード」と他のリクエストをわけています。
URLを叩いた時の初期表示も分けたい場合はセッションの削除を考慮する必要があるかと思います。

リダイレクト時にパラメータをつければ..とも思いましたが、ブラウザでリロードを押した場合には、パラメータが残るのでダメでした。
なので、今回はセッションを使用しました。

Laravel8で検証しています。

ルーティング

ルーティングはこんな感じで作りました。

// ----- 省略 ----- 
Route::get('/test/reload', [TestReloadController::class, "index"])->name('reload.index');
Route::get('/test/reload/before', [TestReloadController::class, "before"])->name('reload.before');
Route::get('/test/reload/next', [TestReloadController::class, "next"])->name('reload.next');

初期表示(/test/reloadにアクセスしたとき)の場合は、TestReloadControllerのindexが動きます。
その他のアクション用に/test/reload/before/test/reload/nextのルートを用意しました。

画面(blade)

初期表示の画面は下記のようにしてみました。

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>reload test screen</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
    </head>
    <body>
        <div class="container mt-4">
            <div class="h3 mb-3">初期表示</div>
            {{ $reload_text }}
            <div class="alert alert-primary">
                {{ $method_action }}
            </div>
                        <a class="btn btn-warning" href="{{ route('reload.before') }}">前のアクション</a>
            <a class="btn btn-primary" href="{{ route('reload.next') }}">次のアクション</a
        </div>
    </body>
</html>

{{ $reload_text }}にリロードか、画面遷移のアクションかを表示するようにしています。
{{ $method_action }}がセッションに保持している値の表示です。

コントローラー

コントローラーを下記のように作成しました。

// ----- 省略 -----
class TestReloadController extends Controller
{
    private $method_action_key = 'method_action_key';

    public function index() {
        $action = session()->get($this->method_action_key);
        $is_reload = ($action == '');

        if(is_null($action)) {
            $reload_text = '初期表示です。';
        } else if ($is_reload) {
            $reload_text = 'リロードです。';
        } else {
            $reload_text = '画面遷移です。';
        }

        // ... 何かのメイン処理 ...

        session()->put($this->method_action_key, '');

        return view('test_reload.index', [
            'method_action' => $action,
            'reload_text' => $reload_text
        ]);
    }

    public function next() {
        session()->put($this->method_action_key, 'next');

        // ... 何かのメイン処理 ...

        return redirect()->route('reload.index');
    }

    public function before() {
        session()->put($this->method_action_key, 'before');

        // ... 何かのメイン処理 ...

        return redirect()->route('reload.index');
    }
}

コードの説明

初期表示メソッド(index)

sessionヘルパーを使用して、セッションで判定しています。

初期表示のときはindexメソッドに入ってきて処理されます。

セッションがない(null)場合は初期表示と判定しています。
セッションの値が、空文字の場合はリロード、それ以外は画面遷移(なんらかのアクション)としています。

if(is_null($action)) {
    $reload_text = '初期表示です。';
} else if ($is_reload) {
    $reload_text = 'リロードです。';
} else {
    $reload_text = '画面遷移です。';
}

最後に、なんらかの処理を行った後に、セッションに空文字を入れています。

session()->put($this->method_action_key, '');

リダイレクトされた場合は、セッションに値が入っているので画面遷移と判定されます。
リロードの場合は、ここで空文字を入れるようにしているため、リロード判定になります。

その他のアクション(next, before)

どちらも同じように下記のように処理をしています。

session()->put($this->method_action_key, 'next');

// ... 何かのメイン処理 ...

return redirect()->route('reload.index');

セッションに処理している内容を入れた後に、何かの処理をして、最後に初期表示画面にリダイレクトします。
nextメソッドではセッションにnext、beforeメソッドではセッションにbeforeをいれています。

動作確認

まず、URLにアクセスすると初期画面が表示されます。

「次のアクション」ボタンを押すと、nextメソッドにアクセスして処理をした後に初期表示画面に戻ってきます。
セッションにいれたnextが表示されました。

同じように「前のアクション」ボタンを押すと、セッションにいれたbeforeが表示されます。

リロードを押した場合は、このように判定されて「リロードです。」と表示されました。

終わりに

セッションを使用して、リロード・初期表示とその他のリクエストを分ける判定をやってみました。
もっと簡単にできる方法がありそうな気もしましたが…
何か他の方法がある場合はコメントにて教えてください😖

コメント

タイトルとURLをコピーしました