Laravel闪存消息在页面上停留多个请求


Laravel flash message stays on page for more than one request

好的,所以我目前正在建立一个博客,在我的添加帖子页面(仪表板)上,我正在使用Javascript sweetalert闪烁一条消息,并且工作正常,但我在其中包含一个链接以查看您刚刚写的帖子。当您单击它并按后退按钮时,闪烁消息再次显示。再说一遍。再一次永远。

这是我在控制器中添加发布操作:

public function createBlogPost(Post $post, Request $request)
{
    $post = new Post;
    $post->title = $request->title;
    $post->slug = str_slug($post->title, '-');
    $post->thumbnail = $request->thumbnail;
    $post->content = $request->content;
    $post->save();
    $mostrecent = DB::table('posts')->orderBy('created_at', 'desc')->first();
    $mslug = $mostrecent->slug;
    $request->session()->put('mslug', $mslug);
    Session::flash('post_success', 'post success');
    return redirect('admin/dashboard');
    // I have tried Session::forget('post_success');
    //              Session::pull('post_success');
    //              Session::flush();
}

我真的不知道问题是什么,但我相当确定它一定与重定向有关,因为我可以在重定向之前忘记密钥并且消息不会闪烁。

任何帮助将不胜感激

(忽略糟糕的PHP,我对这个东西还是很陌生的:P

编辑:我在主文件的底部包含flash.blade.php:

@include('templates.flash')

这是闪存文件:

@if (Session::has('post_success'))
<script>
    swal({
      title: 'Post created!',
      html:
        '<p>Check it out ' +
        '<a href="/blog/{{ Session::get('mslug') }}">here</a>.',
      type: 'success'
    })
</script>
@endif

编辑2:我的路线

Route::get('admin/dashboard', [
    'as' => 'dashboard',
    'uses' => 'AdminController@dashboard'
]);
Route::post('admin/dashboard', [
    'as' => 'createblogpost',
    'uses' => 'AdminController@createBlogPost'
]);

首先,为了解释你的问题,你应该看看这里,但你的问题的基本要点与拉拉维尔无关。

当您在浏览器中按下后退按钮时,浏览器本身会尽力将您带回您所在的页面,并尝试通过缓存一些数据来帮助您,这些数据将允许您准确地返回到上次中断的位置,这通常意味着如果您正在填写表格, 当您按下后退按钮时,表格仍将为您填写。

因此,在您的情况下,使用 Laravel 的Session::flash确实只会保留一个请求的消息,但这并不一定意味着您的浏览器不会缓存数据本身。因此,当您点击后退按钮时,您的浏览器会向您闪烁成功消息。

可能的解决方案:

  1. 从用户的角度来看,不是最优雅的,但可能对您来说最容易实现:您可以包括一个链接,如"返回仪表板"或类似的东西,用于要单击的用户,该用户将把他发送回仪表板一种从头开始重新加载页面的方式,而不是使用后退按钮。

  2. 您可以更改方法并使用Ajax加载闪存消息而不是会话。这样当你点击后退按钮时页面将被重新加载,但不会调用 Ajax并且您不会看到闪光消息。这将允许使用后退按钮,但会迫使您在代码中做更多的工作。

  3. 在这种情况下,另一种选择是,尽管它需要一些研究和测试,并且只有在您确定它不会产生负面副作用时才应使用,但实际上是告诉您的浏览器停止缓存数据。

有几种方法可以执行第三种选择:

如果包括以下内容:

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

在你的控制器中,或者作为一个新的中间件ClearBrowserCache或类似的东西,那么你可以通过PHP完成这一点,这是理想的,因为它可以与Laravel很好地集成,你不必担心用户没有启用javascript。唯一的问题是,虽然它在Chrome中工作,但它现在在Safari 9上对我不起作用。

类似的替代方法是使用 Javascript 来实现相同的目标,方法是将此脚本添加到您的页面:

window.onpageshow = function(evt) {
    if (evt.persisted) {
        document.body.style.display = "none";
        location.reload();
    }
};

此脚本确实适用于 Safari,但不适用于 Chrome。

因此,如果您选择最后一个选项以查看哪些选项有效并在您认为需要支持的任何浏览器中对其进行测试,并找到解决方案或针对不同浏览器的解决方案组合,那么实际上将由您进行更多的研究。