Laravel 对于多个请求,Flash 消息停留在页面上

Laravel flash message stays on page for more than one request

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

这是我在控制器中添加 post 的操作:

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')

这是 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无关。

当您在浏览器中按下后退按钮时,浏览器本身会尽力将您带回到您所在的页面,并且它会尝试通过缓存一些数据来帮助您 return 到您离开的地方,通常这意味着如果您正在填写表格,当您按下后退按钮时,表格仍会为您填写。

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

可能的解决方案:

  1. 从用户的角度来看不是最优雅的,但对您来说可能是最容易实现的:您可以 包括 link 之类的 'back to dashboard' 或类似的东西,因为 用户点击哪个将使他返回到仪表板 页面将从头开始重新加载的一种方式,而不是使用 后退按钮。

  2. 你可以改变你的方法并使用Ajax加载你的flash 消息而不是会话。这样当你按下后退按钮时 页面将重新加载,但 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。

因此,如果您选择最后一个选项以查看有效的方法并在您认为需要支持的任何浏览器中测试它并找到解决方案或组合,那么您真的需要做更多的研究针对不同浏览器的解决方案。