2
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Laravel】フラッシュメッセージが再表示されるのを防ぐ

Last updated at Posted at 2022-06-26

やりたいこと

flashメソッドやwithメソッドを使ってフラッシュメッセージを表示させる際、
「当該ページでフラッシュメッセージを表示」→「他のページに移動」→「ブラウザの戻るボタンで元のページに戻る」
上記を行うと同じフラッシュメッセージが再表示されてしまう。これを防ぎたい。

実装方法

以下コードのように、phpで作成したユニーク値をJavaScriptを使用してブラウザのストレージに保存し「一度目の表示かどうか」を判定する。具体的なコードの説明は本記事の最下部に載せています。

example.blade.php
<div id="FlashMessage">
    <p class="FlashMessage_Text">
        {{session('message')}}
    </p>
</div>

<script>
    if( "{{session('message')}}" ){
      const messageIdValue = "{{ uniqid() }}";
      if (sessionStorage) {
        if (sessionStorage.getItem('messageId') === messageIdValue) {
          document.getElementById('FlashMessage').style.display = "none";
        }else{
          sessionStorage.setItem('messageId', messageIdValue);
        }
      }    
    }
</script>

そもそもフラッシュメッセージの仕組みは?

サーバのSessionデータにメッセージを保存し、それを呼び出している。

通常であればSessionデータに保存した値は特定の条件が満たされるまで保持される。
しかし、flashメソッドやwithメソッドを使用した場合は、Sessionに値を保存した後、1回目のリクエスト(ページ遷移)が終了するとその値が削除される。
なので、特定の操作(記事投稿やログインなど)のあとに1度だけフラッシュメッセージを表示することができる。

Sessionってなんだっけ?という場合は下記の記事様がわかりやく解説してくださってます。

なぜブラウザの戻るボタンだと再表示される?

ブラウザのキャッシュでページを表示しているから。

通常、ブラウザの戻るボタンは、元のページ宛に改めてリクエストを送っているわけではなく、ブラウザのキャッシュによりページを表示している。つまりサーバとは通信していない。なのでSessionデータに保存したメッセージがサーバ側で消えていても関係ない。

コードの説明

example.blade.php
<div id="FlashMessage">
    <p class="FlashMessage_Text">
        {{session('message')}}
    </p>
</div>

<script>
    //Sessionデータにメッセージが有るかどうかを確認
    if( "{{session('message')}}" ){
      //phpのuniqid関数でユニーク値をセット
      const messageIdValue = "{{ uniqid() }}";
      //主要ブラウザはsessionStorageに対応しているが、念のため確認
      if (sessionStorage) {
        //messageIdの値が同じだったら、フラッシュメッセージをdisplay:none;する
        if (sessionStorage.getItem('messageId') === messageIdValue) {
          document.getElementById('FlashMessage').style.display = "none";
        }else{
          //messageIdがない場合は新しくセット。
          //messageIdは有るが値が違う場合は上書き。
          sessionStorage.setItem('messageId', messageIdValue);
        }
      }    
    }
</script>

ユニーク値はphpで作っているので、ブラウザの戻るボタンを押して同じページに戻った場合、messageIdValueの値は1度目の表示時と同じになります(前述の通りキャッシュでページを表示しているため)。
なので、このmessageIdValueをsessionStorageに保存→照合することにより1度目の表示なのかどうかが判定できます(ちなみにsessionStorageはブラウザのストレージなのでサーバ側のSessionデータとは異なるものです)。

2
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?