Laravel 5.5中Session::put()存入'favicon.ico'问题求助
问题原因与解决方案
这个问题我之前排查过,其实是浏览器自动请求favicon.ico搞的鬼!
具体原因分析
当你访问带/en的路由时,第一次请求确实会把'en'存入Session,但浏览器加载页面后,会自动发起第二个请求去获取/favicon.ico(网站图标)。如果你的路由规则设计得比较宽泛(比如把locale设为一个无约束的路由参数,类似Route::get('{locale}/someroute', ...)),这个/favicon.ico请求会被路由解析成locale参数为'favicon.ico',此时中间件就会把这个值覆盖到Session里。
而当你加上dd($locale)时,第一个请求直接终止了,浏览器根本没机会发起favicon的请求,所以Session里保留的是预期的'en';一旦去掉dd,后续的favicon请求就会覆盖掉之前的Session值,导致你看到的是'favicon.ico'。
解决办法
这里给你几个可行的方案,按需选择:
- 直接排除favicon请求:在中间件最开头加上判断,跳过favicon的处理逻辑:
// 先判断是否是favicon请求,是就直接放行 if ($request->is('favicon.ico')) { return $next($request); } // 你的原有逻辑 $locale = $request->route('locale'); if ($locale != null) { Session::put('_lang', $locale); } else { // 这里的dd可以去掉,或者换成日志调试 // dd($request->session()); }
- 给locale参数加路由约束:在路由定义时,用正则约束
locale只能匹配合法的语言代码(比如两位小写字母),这样favicon.ico就不会被误匹配成locale参数了:
Route::get('{locale}/someroute', function ($locale) { // 你的路由逻辑 })->where('locale', '[a-z]{2}'); // 只匹配en、zh这类两位语言代码
- 优先定义favicon路由:在所有locale相关路由之前,先定义一个专门处理favicon的路由,让它直接返回图标文件,不经过后续路由匹配:
// 优先处理favicon请求 Route::get('favicon.ico', function () { return response()->file(public_path('favicon.ico')); }); // 再定义你的locale路由 Route::get('{locale}/someroute', ...);
额外提醒
Web中间件会作用于所有web请求,除了favicon,浏览器还可能自动请求manifest.json、robots.txt等文件,建议在处理这类全局逻辑时,都考虑排除这些非业务请求,避免干扰正常逻辑。
内容的提问来源于stack exchange,提问作者Jacobo de la Rosa
相关产品推荐
相关产品推荐

