【问题标题】:Session data not preserved after redirection重定向后不保留会话数据
【发布时间】:2016-03-30 01:49:13
【问题描述】:

我正在尝试实现一些自定义 Flash 消息,但在重定向后会话数据被破坏时遇到了一些问题。

以下是我创建 Flash 消息的方法:

flash('Your topic has been created.');

这是flash()函数的声明:

function flash($message, $title = 'Info', $type = 'info')
{   
    session()->flash('flash', [
        'message' => $message,
        'title' => $title,
        'type' => $type,        
    ]); 
}

这就是我使用 SweetAlerts 检查会话/显示 Flash 消息的方式。此代码包含在我在所有 Blade 模板中扩展的主布局文件的底部。

@if(Session::has('flash'))
    <script>
        $(function(){
            swal({
                title: '{{ Session::get("flash.title") }}',
                text : '{{ Session::get("flash.message") }}',
                type : '{{ Session::get("flash.type") }}',
                timer: 1500,
                showConfirmButton: false,           
            })
        });         
    </script>
@endif

如果我在显示视图之前调用flash() 函数,上面的代码将起作用,如下所示:

public function show($slug)
{
    flash('It works!');
    return view('welcome');
}

但是,如果我在重定向到另一个页面之前调用它,它将不起作用,如下所示:

public function show($slug)
{
    flash('It does not work');
    return redirect('/');
}

为什么重定向时会话数据会丢失?我怎样才能让它持久化,以便我可以显示我的 Flash 消息?

【问题讨论】:

  • 能否请您检查重定向前后的网址?有时您使用www. 在域上并重定向到没有www. 的域,在这种情况下您将看不到会话

标签: php laravel session redirect laravel-5.2


【解决方案1】:

【讨论】:

    【解决方案2】:

    事实证明,在 Laravel 5.2 中,必须将路由封装在 Web 中间件中才能使会话正常工作。

    这解决了它:

    Route::group(['middleware' => ['web']], function () {
        // ...
        Route::post('/topics/{slug}/answer', 'PostsController@answer');
        Route::post('/topics/{slug}/unanswer', 'PostsController@unanswer');
        Route::post('/topics/{slug}/delete', 'PostsController@delete');
    });
    

    【讨论】:

    • 我有同样的问题,但是这个解决方案对我不起作用。
    • @FlyingAtom 是的,它已经改变了,但是当我问这个问题时,你必须手动完成。 ;)
    【解决方案3】:

    我发现有必要在所有路由上应用 web 中间件。 Drown 曾提到这样做,但自 2016 年 3 月 23 日起,Taylor Otwell 将默认 RouteServiceProvider 更改为 https://github.com/laravel/laravel/commit/5c30c98db96459b4cc878d085490e4677b0b67ed

    通过该更改,Web 中间件将自动应用于所有路由。如果您现在在您的 routes.php 中再次应用它,您将看到 web 在路由列表中出现两次 (php artisan route:list)。这正是使闪存数据被丢弃。

    另见:https://laracasts.com/discuss/channels/laravel/session-flash-message-not-working-after-redirect-route/replies/159117

    【讨论】:

      【解决方案4】:

      使用闪存数据重定向是这样完成的:

      redirect("/blog")->with(["message"=>"Success!"]);
      

      早期的 Laravel 5.2 版本中,只有当你的路由在 web middleware 组内时,你的所有 FlashSession 数据才会被存储。

      Laravel 5.2.34 开始,所有路由都默认使用网络中间件。如果您将它们再次放入中间件 web 组,您将在您的路由上应用 web 中间件两次 - 这样的路由将无法保留 FlashSession 数据。

      【讨论】:

        【解决方案5】:

        在 Laravel 5.2.34 中,所有路由都默认使用 Web 中间件。

        因此,改变这个:

        Route::group(['middleware' => ['web']], function () { // This will use 2 web middleware
        
            // ...
        
            Route::post('/foo', 'FooController@foo');
        
        });
        

        到这里:

        Route::group([], function () { // This will use the default web middleware
        
            // ...
        
            Route::post('/foo', 'FooController@foo');
        
        });
        

        然后在你的控制器中你可以使用:

        class FooController extends Controller
        {
            ...
        
            public foo() 
            {
                ...
        
                return redirect('/foo')->withSuccess('Success!!');
                // or
                return redirect('/foo')->with(['success' => 'Success!!']);
            }
        
            ...
        }
        

        【讨论】:

          【解决方案6】:

          我遇到的问题是 Session::save() 阻止 swal 在重定向后显示。

          所以您需要从中间件中删除 Session::save()session()-&gt;save();

          【讨论】:

          • 问题出在中间件内部Session::save(),请更换。
          • @Harry Bosh,花一整天的时间来解决这个问题,直到看到你的解决方案。它对我有用。谢谢。
          【解决方案7】:

          请查看APP/kernel.php

          \Illuminate\Session\Middleware\StartSession::class,

          多次定义

          protected $middleware = [
              \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
              \Illuminate\Session\Middleware\StartSession::class,
            ];
          
          protected $middlewareGroups = [
              'web' => [
                  \App\Http\Middleware\EncryptCookies::class,
                  \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
                  \Illuminate\Session\Middleware\StartSession::class,
                  \Illuminate\View\Middleware\ShareErrorsFromSession::class,
                  \App\Http\Middleware\VerifyCsrfToken::class,
                  \Illuminate\Routing\Middleware\SubstituteBindings::class,
              ],
          

          您可以评论任何一个或删除它。我们只需要定义一次。

          【讨论】:

          • 是的!谢谢!许多不同的问题都解决了这个问题,但没有一个为我解决了这个问题。这正是问题所在。中间件和网络组中间件都有会话开始。史诗。谢谢!
          • 那是正确的答案。谢谢!
          【解决方案8】:

          检查您的 App\Kernel.php 文件。 \Illuminate\Session\Middleware\StartSession::class 可能有多行, 来自 $middlewareGroups 的评论之一。

          protected $middleware = [
                  \App\Http\Middleware\TrustProxies::class,
                  \App\Http\Middleware\CheckForMaintenanceMode::class,
                  \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
                  \Illuminate\Session\Middleware\StartSession::class,
                  \App\Http\Middleware\TrimStrings::class,
                  \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
              ];
          
          protected $middlewareGroups = [
                  'web' => [
                      \App\Http\Middleware\EncryptCookies::class,
                      \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
                      **\Illuminate\Session\Middleware\StartSession::class,**
                      // \Illuminate\Session\Middleware\AuthenticateSession::class,
                      \Illuminate\View\Middleware\ShareErrorsFromSession::class,
                      \App\Http\Middleware\VerifyCsrfToken::class,
                      \Illuminate\Routing\Middleware\SubstituteBindings::class,
                  ],
          

          【讨论】:

            【解决方案9】:

            除了 @Harry Bosh 回答之外,

            在 Laravel 中,当Session::save() 发生在中间件内部时,会出现问题, 这会使 _flash 会话在重定向后消失发生

            这可以通过使用替代解决:

            // replace your Session::save() to this
            
            session(['yoursessionvar' => $examplevar]); // this will save laravel session
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2016-08-27
              • 2013-11-15
              • 1970-01-01
              • 2020-07-16
              • 2017-07-23
              • 2014-12-21
              • 2015-02-05
              相关资源
              最近更新 更多