简体   繁体   English

重定向后不保留会话数据

[英]Session data not preserved after redirection

I'm trying to implement some custom flash messages and I'm having some issues with the session data being destroyed after a redirect.我正在尝试实现一些自定义 Flash 消息,但在重定向后会话数据被破坏时遇到了一些问题。

Here's how I create my flash messages :以下是我创建 Flash 消息的方法:

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

Here's the declaration of the flash() function :这是flash()函数的声明:

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

And here is how I'm checking the session/displaying the flash messages, using SweetAlerts.这是我使用 SweetAlerts 检查会话/显示 Flash 消息的方式。 This code is included at the bottom of the main layout file that I'm extending in all my Blade templates.此代码包含在我在所有 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

The code above will work if I call the flash() function before displaying a view, like so :如果我在显示视图之前调用flash()函数,上面的代码将起作用,如下所示:

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

However, it will not work if I call it before doing a redirect to another page, like so :但是,如果我在重定向到另一个页面之前调用它,它将不起作用,如下所示:

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

Why is the session data lost on redirect?为什么重定向时会话数据会丢失? How can I make it persists so that I can display my flash message?我怎样才能让它持续存在,以便我可以显示我的 Flash 消息?

I found out that it is necessary to apply the web middleware on all routes.我发现有必要在所有路由上应用 web 中间件。 Drown has mentioned to do so, but since March 23st 2016, Taylor Otwell changed the default RouteServiceProvider at https://github.com/laravel/laravel/commit/5c30c98db96459b4cc878d085490e4677b0b67ed Drown 已经提到这样做,但自 2016 年 3 月 23 日以来,Taylor Otwell 在https://github.com/laravel/laravel/commit/5c30c98db96459b4cc878d085490e4677b0b67ed更改了默认的 RouteServiceProvider

By that change the web middleware is applied automatically to all routes.通过该更改,Web 中间件会自动应用于所有路由。 If you now apply it again in your routes.php, you will see that web appears twice on the route list ( php artisan route:list ).如果你现在在你的 routes.php 中再次应用它,你会看到web在路由列表中出现了两次( php artisan route:list )。 This exactly makes the flash data discard.这正是使闪存数据丢弃。

Also see: https://laracasts.com/discuss/channels/laravel/session-flash-message-not-working-after-redirect-route/replies/159117另请参阅: https : //laracasts.com/discuss/channels/laravel/session-flash-message-not-working-after-redirect-route/reply/159117

It turns out that with Laravel 5.2, the routes have to be wrapped in the web middleware for the session to work properly.事实证明,在 Laravel 5.2 中,路由必须包含在 Web 中间件中,会话才能正常工作。

This fixed it :这修复了它:

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

The issue i had was Session::save() preventing swal from showing after redirect.我遇到的问题是Session::save()阻止 swal 在重定向后显示。

so you need to remove Session::save() or session()->save();所以你需要删除Session::save()session()->save(); from middleware来自中间件

Please check APP/kernel.php请检查APP/kernel.php

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

is define multiple times被定义多次

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,
    ],

You can comment any one or delete it.您可以评论任何一个或删除它。 We need to define one time only.我们只需要定义一次。

With Laravel 5.2.34, all routes are using web middleware by default.在 Laravel 5.2.34 中,所有路由默认都使用 web 中间件。

Therefore, change this:因此,改变这一点:

Route::group(['middleware' => ['web']], function () { // This will use 2 web middleware

    // ...

    Route::post('/foo', 'FooController@foo');

});

To this:对此:

Route::group([], function () { // This will use the default web middleware

    // ...

    Route::post('/foo', 'FooController@foo');

});

And then in your controller you could use:然后在您的控制器中,您可以使用:

class FooController extends Controller
{
    ...

    public foo() 
    {
        ...

        return redirect('/foo')->withSuccess('Success!!');
        // or
        return redirect('/foo')->with(['success' => 'Success!!']);
    }

    ...
}

Redirect with flash data is done like this:使用闪存数据重定向是这样完成的:

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

In early Laravel 5.2 versions, all of your Flash and Session data are stored only if your routes are inside web middleware group.早期的 Laravel 5.2版本中,只有当你的路由在web middleware组中时,你所有的FlashSession数据才会被存储。

As of Laravel 5.2.34 , all routes are using web middleware by default .Laravel 5.2.34 开始,所有路由都默认使用 web 中间件 If you will put them into middleware web group again, you will apply web middleware on your routes twice - such routes will be unable to preserve Flash or Session data.如果你再次将它们放入中间件 web 组,你将在你的路由上应用两次 web 中间件 - 这样的路由将无法保留FlashSession数据。

Check your App\\Kernel.php file.检查您的 App\\Kernel.php 文件。 There may be multiple lines of \\Illuminate\\Session\\Middleware\\StartSession::class, Comment one from $middlewareGroups. \\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,
        ],

Additional to @Harry Bosh answer,除了@Harry Bosh 的回答,

In Laravel there an issue when Session::save() happen inside the middleware, this make _flash session gone after redirection happen在 Laravel 中,中间件内部发生Session::save()Session::save()出现问题,这会使_flash 会话在重定向发生后消失

this can be fix by using alternative :这可以通过使用替代解决方案:

// replace your Session::save() to this

session(['yoursessionvar' => $examplevar]); // this will save laravel session

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM