导航离开并使用后退按钮后,Laravel 5 flash 消息再次闪烁

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30038969/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 11:29:54  来源:igfitidea点击:

Laravel 5 flash message flashes again after navigating away and using back button

laravel

提问by Ahzrael

In my controller im trying to redirect back with a Flash message in laravel 5. This all works great. The problem is no matter how i set it up the flash message always re-appears if i navigate away and then come back by using the browsers 'back button'.

在我的控制器中,我尝试使用 laravel 5 中的 Flash 消息重定向回来。这一切都很好。问题是,无论我如何设置,如果我导航离开然后使用浏览器的“后退按钮”返回,Flash 消息总是会重新出现。

So i have a users list with a delete button next to each user. When i click the delete button it calls my controller method to destroy. I made a little conditional in there that redirects back with an error if i am trying to delete an owner. I tried the following different ways to redirect back but with all i wind up with the same problem that the message shows again after navigating away and coming back via the browsers 'back button'.

所以我有一个用户列表,每个用户旁边都有一个删除按钮。当我单击删除按钮时,它会调用我的控制器方法来销毁。我在那里做了一些有条件的重定向,如果我试图删除一个所有者,则会出现错误。我尝试了以下不同的重定向方式,但最终我遇到了同样的问题,即在导航离开并通过浏览器的“后退按钮”返回后再次显示该消息。

1

1

return Redirect::route('users')->with('error_message', 'Some error msg');

2

2

Session::flash('error_message', 'Some error msg');
return Redirect::to('users'); 

In my view i pick it up like this:

在我看来,我是这样理解的:

@if (Session::has('error_message'))
     {{ Session::get('error_message') }}
@endif

So that works good, i get the message. But as soon as for example i click a user in my user list to go to the details page and press the browser 'back button', the message flashes again. I dont get why it keeps flashing that data, i was under the impression that it just flashes one time.

所以这很好用,我收到了消息。但是,例如,只要我单击用户列表中的某个用户以转到详细信息页面并按浏览器的“后退按钮”,消息就会再次闪烁。我不明白为什么它不断闪烁数据,我的印象是它只闪烁一次。

Even if i try to clear it right after displaying (like below), it doesnt matter, it will always re-appear?

即使我尝试在显示后立即清除它(如下所示),也没关系,它总是会重新出现?

{!! Session::forget('error_message') !!}

采纳答案by Joel Hinz

Generally, when the user clicks the back button in the browser, the browser tries to display the contents of the previous page without reloading it. So it's likely not Laravel flashing to the session again, but the browser trying to help you out by caching the page for you.

通常,当用户点击浏览器中的后退按钮时,浏览器会尝试显示上一页的内容而不重新加载它。因此,很可能不是 Laravel 再次闪烁到会话中,而是浏览器试图通过为您缓存页面来帮助您。

回答by shukshin.ivan

You can show flash messages using javascript and use SessionStorageto stop repeating messages. Browser cache doesn't know if browser already shown a message, but we can use SessionStorageto check it before display.

您可以使用 javascript 显示 Flash 消息并用于SessionStorage停止重复消息。浏览器缓存不知道浏览器是否已经显示了一条消息,但我们可以SessionStorage在显示前检查它。

<div id="flash-container"></div>
...

var popupId = "{{ uniqid() }}";

if(sessionStorage) {
   // prevent from showing if it exists in a storage (shown);
   if(!sessionStorage.getItem('shown-' + popupId)) {
      $('#flash-container').append("<div>{{ session('status') }}</div>");
   }
   sessionStorage.setItem('shown-' + popupId, '1');
}

回答by Ruben Arevalo

For those of you not concerned with back button:

对于那些不关心后退按钮的人:

@if (Session::has('error_message'))
 {{ Session::get('error_message') }}
 {{ Session::forget('error_message') }}
@endif

and if that doesnt make it clear out, try:

如果这没有说清楚,请尝试:

@if (Session::has('error_message'))
 {{ Session::get('error_message') }}
 {{ Session::forget('error_message') }}
 {{ Session::save() }}
@endif

回答by Payal

Step 1 : create one middleware using following command:

第 1 步:使用以下命令创建一个中间件:

php artisan make:middleware PreventBackHistory

php artisan make:middleware PreventBackHistory

Step 2:

第2步:

replace content of PreventBackHistory.php with following content:

用以下内容替换 preventBackHistory.php 的内容:

namespace App\Http\Middleware;

use Closure;

class PreventBackHistory { 

    /*  Handle an incoming request. 
     *  @param \Illuminate\Http\Request $request
     *  @param \Closure $next 
     *  @return mixed 
     */ 
    public function handle($request, Closure $next) 
    { 
        $response = $next($request);
        return $response->header('Cache-Control','no-cache, no-store, max-age=0, must-revalidate') 
                        ->header('Pragma','no-cache')                 
                        ->header('Expires','Sun, 02 Jan 1990 00:00:00 GMT'); 
    } 
}

step 3: register middleware in kernal.php

第三步:在kernal.php中注册中间件

'preventBackHistory' => \App\Http\Middleware\PreventBackHistory::class,

'preventBackHistory' => \App\Http\Middleware\PreventBackHistory::class,

step 4: use middleware in your controller's construstor

第 4 步:在控制器的构造函数中使用中间件

public function __construct() 
{ 
    $this->middleware('preventBackHistory');
    $this->middleware('auth'); 
}

And good to go :)

很高兴去:)

回答by Michael

I've just come across this problem and I think the only way to get around it is to AJAX load your flash messages into the page.

我刚刚遇到这个问题,我认为解决它的唯一方法是 AJAX 将您的 Flash 消息加载到页面中。

I've not tested this yet but I assume that when the user goes back and the AJAX request fires the previous flash messages will have already been cleared.

我尚未对此进行测试,但我假设当用户返回并触发 AJAX 请求时,先前的 flash 消息将已被清除。

回答by Ahzrael

Well it seems it was indeed the browser cache and after adding the code to stop cache it was ok and the message disappeared. It still is weird to me that i had to add this code to the controller to stop it from caching:

好吧,它似乎确实是浏览器缓存,在添加了停止缓存的代码后就可以了,消息消失了。我不得不将此代码添加到控制器以阻止它缓存,这对我来说仍然很奇怪:

header('Cache-Control: no-store, private, no-cache, must-revalidate'); header('Cache-Control: pre-check=0, post-check=0, max-age=0, max-stale = 0', false);
header('Pragma: public');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); 
header('Expires: 0', false); 
header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
header ('Pragma: no-cache');

Or this in the htaccess:

或者在 htaccess 中:

<IfModule mod_headers.c>
    Header set Cache-Control "no-cache, no-store, must-revalidate"
    Header set Pragma "no-cache"
    Header set Expires 0
</IfModule>

But that seemed a bit overkill to me ;)

但这对我来说似乎有点矫枉过正;)