Laravel 9控制器中如何获取i18Next的当前语言环境?
嘿,我懂你的困扰——前端用i18next切换语言挺顺畅,但后端Laravel控制器里用Lang::locale()这些方法就是拿不到当前语言,对吧?这是因为i18next是纯前端的国际化库,它的语言切换只在浏览器端生效,后端Laravel的locale配置是独立的,两者默认没有同步机制。
要解决这个问题,核心思路就是把前端选中的语言同步到后端,下面是具体的实现步骤:
1. 前端切换语言时,同步语言标识到后端
在你的languageChanged事件回调里,新增一段代码,把当前切换后的语言(lng参数)发送给后端接口,用来存到Session或者Cookie中:
i18next.on('languageChanged', function(lng) { // 保留原来的更新页面文本逻辑 selector.forEach(function(item) { item.innerHTML = i18next.t(item.getAttribute("data-i18n")); }); // 新增:把语言发送到后端 fetch('/set-locale', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content }, body: JSON.stringify({ locale: lng }) }); });
2. 后端接收语言并存储
首先创建一个路由,用来处理前端的语言同步请求:
// routes/web.php Route::post('/set-locale', [LocaleController::class, 'setLocale']);
然后在对应的控制器里写处理逻辑,把语言存到Session,同时可以设置Cookie让下次请求自动带上:
// app/Http/Controllers/LocaleController.php use Illuminate\Http\Request; public function setLocale(Request $request) { $locale = $request->input('locale'); // 先验证语言是否在你的项目支持列表里(建议在config/app.php里配置supported_locales数组) $supportedLocales = config('app.supported_locales'); if (in_array($locale, $supportedLocales)) { session()->put('locale', $locale); // 设置Cookie,有效期30天 return response()->json(['success' => true])->cookie('locale', $locale, 60*24*30); } return response()->json(['success' => false], 400); }
3. 用中间件自动设置后端Locale
创建一个中间件,每次请求时从Session或Cookie里读取语言,设置到Laravel应用的locale中:
// app/Http/Middleware/SetLocale.php <?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; class SetLocale { public function handle(Request $request, Closure $next) { // 优先级:Session > Cookie > 默认语言 $locale = session('locale') ?? $request->cookie('locale') ?? config('app.locale'); $supportedLocales = config('app.supported_locales'); if (in_array($locale, $supportedLocales)) { app()->setLocale($locale); } return $next($request); } }
然后把这个中间件加到app/Http/Kernel.php的web中间件组里,这样所有web请求都会自动应用语言设置:
protected $middlewareGroups = [ 'web' => [ // ...其他中间件 \App\Http\Middleware\SetLocale::class, ], ];
4. 现在控制器里就能拿到正确的语言了
做完上面的步骤,你在控制器里用app()->getLocale()、Lang::locale()或者Config::get('app.locale')都能获取到和前端i18next一致的语言环境啦!
另外补充个小技巧:如果不想用Session/Cookie,也可以每次请求时在URL参数(比如?locale=de)或者请求头里带语言标识,然后在中间件里读取设置,但这种方式需要每次请求都携带,不如Session/Cookie方便。
备注:内容来源于stack exchange,提问作者Jessica Kimble

