You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 9:404页面使用视图合成器时出现Session未设置请求错误

解决视图合成器在404页面访问session报错及session重置问题

问题分析

全局视图合成器会作用于所有视图(包括404错误视图),但Laravel默认情况下,StartSession中间件属于web中间件组,只有匹配到路由的请求才会执行该中间件。404页面是路由匹配失败后直接渲染的,此时session还未初始化,所以视图合成器里调用session()会抛出Session store not set on request错误。

而把StartSession移到全局中间件组后,虽然错误页面能访问session,但会破坏Laravel的session生命周期逻辑:全局中间件会在所有请求(包括静态资源、API请求)中执行,且缺少web组中其他配套中间件(如ShareErrorsFromSession、VerifyCsrfToken)的协作,导致session数据无法被正确持久化,每次刷新都会重置。


可行解决方案

方案1:在视图合成器中判断session可用性

修改Composer.php的compose方法,先检查当前请求是否已初始化session,再决定是否从session取值:

public function compose(View $view)
{
    // 默认使用配置文件中的货币
    $currency = config('app.currency');
    
    // 仅当session已初始化时,从session获取值
    if ($this->request->hasSession()) {
        $currency = $this->request->session()->get('currency', $currency);
    }
    
    $view->with('currency', $currency);
}

这种方式最简单,既保留全局视图合成器的作用范围,又避免错误页面报错。

方案2:让错误页面走web中间件组

在routes/web.php中添加一个fallback路由,让404请求先经过web中间件再触发错误:

Route::fallback(function () {
    abort(404);
})->middleware('web');

这样404页面渲染前会执行StartSession中间件,session可正常访问,视图合成器能正确取到session中的货币值。

方案3:缩小视图合成器的作用范围

如果不是所有视图都需要$currency变量,可以在ViewServiceProvider.php中指定合成器作用的视图,排除错误视图:

// 只作用于布局和业务页面视图,排除errors目录下的错误视图
View::composer(['layouts.*', 'pages.*'], \App\Http\View\Composers\Composer::class);

这种方式从根源避免错误视图触发合成器,自然不会出现session相关错误。


内容的提问来源于stack exchange,提问作者Tony Sawlwin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 02:47:28