这让我疯了好几个星期了: 如何在404页面上提供会话?我只是 将404错误页面嵌入我的默认模板中。它还显示了导航栏 和页脚但是如何在404上保持用户登录?
在404 Auth :: check()上总是返回false,其他特定于会话的其他内容为null或为空。
如何在(404)错误页面上启用会话?
答案 0 :(得分:8)
你可以做的是,在app / http / Kernel.php中添加以下代码块:
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
在$ middleware变量中。所以它看起来像:
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
];
它对我有用,我希望它对你也有用。
答案 1 :(得分:3)
所以我知道这是一个老问题,但是如果有人发现它有用,这就是我的处理方式:
在我的App/Exceptions/Handler.php
中,我将默认的render
方法更改为:
public function render($request, Exception $exception) {
\Route::any(request()->path(), function () use ($exception, $request) {
return parent::render($request, $exception);
})->middleware('web');
return app()->make(Kernel::class)->handle($request);
}
这达到2个要求:
web
中间件都能针对请求正确运行实际上,这是将web
中间件组设置为发生错误时默认运行的决定。 Laravel通常不会在错误页面上运行任何中间件组。您当然可以指定其他中间件或其他路由参数,如果您想要或使用其他条件,例如如果路径以api/
开头,则使用api
中间件,而不是使其更加一致。
希望这对某人有帮助。
答案 2 :(得分:1)
只是为了扩展现有答案:确保从$ middlewareGroups中删除该中间件(如果它也在那里),因此您不要将中间件应用两次。
你最终会得到这样的东西:
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::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,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
据我所知,这是因为处理会话的中间件,因为在Web组中只应用于在web.php上路由的那些页面。由于默认错误处理不会重定向到路由页面,因此我们无法访问会话。
这样,中间件将应用于所有页面,而不仅仅是那些在web.php上路由的页面,包括错误的页面。
我最初找到了here这个消息,但是花了一些时间才明白为什么会发生这种情况(我觉得我已经把它弄错了,请随时确认或纠正这个问题。)
希望它有所帮助,它在Laravel 5.4上为我工作
答案 3 :(得分:0)
为避免在api中间件有其他异常或接收请求时出现问题,请将App / Exceptions / Handler.php中的render函数更改为:
public function render ($request, Exception $exception)
{
if ($this->isHttpException($exception)) {
switch ($exception->getStatusCode()) {
case '404':
\Route::any(request()->path(), function () use ($exception, $request) {
return parent::render($request, $exception);
})->middleware('web');
return app()->make(Kernel::class)->handle($request);
break;
default:
return $this->renderHttpException($exception);
break;
}
} else {
return parent::render($request, $exception);
}
}
答案 4 :(得分:0)
我真的看不到这些答案有多么好。它们过于复杂,倾向于建议使用其他路由来重建内核,从而导致内存和CPU使用率激增,仅产生404页。
我建议只创建所需的路由,而不要使用Laravel页面建议的自动错误页面。在较新的Laravel版本中,此功能已得到改进,但是对于此版本,我只建议以下内容:
routes.php
Route::group(['middleware' => ['web']], function ($router) {
$router->get('/404', [
'uses' => 'HttpErrorController@404',
'as' => 'errors.404',
]);
});
很显然,这取决于您的设置方式,这就是我使用路由并创建HttpErrorController
来处理路由的原因,这就是为什么它已经在web
中间件组中的原因
App\Exceptions\Handler.php
public function render($request, Exception $exception)
{
if ($this->isHttpException($exception) && $exception->getStatusCode() === 404)
{
return redirect()->route('404');
}
return parent::render($request, $exception);
}
您可以按照自己认为合适的任何方式进行处理,在其中添加一个开关,检查是否为json请求,然后以其他方式进行处理等
答案 5 :(得分:0)
对于Laravel 5.5.5或更高版本,只需使用Route::fallback:
Route::fallback('PagesController@notFound');
这将帮助您自定义可以访问所有会话以及更多内容的404视图。