【问题标题】:Laravel localization middleware causing ERR_TOO_MANY_REDIRECTSLaravel 本地化中间件导致 ERR_TOO_MANY_REDIRECTS
【发布时间】:2021-01-09 10:55:20
【问题描述】:

我正在尝试在 laravel 应用程序中设置本地化,但我的中间件似乎导致了 ERR_TOO_MANY_REDIRECTS 错误。该站点将在每个地区略有不同,我正在使用 laravel lang/ 文件来交换电话号码等。这没问题。当我更改语言环境时,我会从 lang 文件中获得正确的数字。当我只有中间件来检查 cookie 是否已设置为设置也可以工作的语言环境时。

我还有中间件可以忘记本地化路由的前缀,因此我不必使用语言环境参数更新我的方法。

如果在我的中间件中使用允许的语言环境设置了 cookie,我的问题是设置 url 前缀。如果语言环境是“en”,我也想忽略前缀,因为它将是默认值。

下面是代码

routes/web.php

Route::get('/', 'HomeController@index')->name('home');
Route::get('/reader/{identifier}', 'ReaderController@show')->name('reader');
Route::get('/locale/{locale}', SetLocaleController::class)->name('set.locale');

Route::group(['prefix' => '{locale?}', 'where' => ['locale' => implode('|', array_keys(config('app.allowed_locales')))], 'middleware' => 'redirect.localization'], function () {
    Route::get('/', 'HomeController@index')->name('home');
    Route::middleware('forget.prefix')->get('/reader/{identifier}', 'ReaderController@show')->name('reader');
});

Middleware/Localization.php - 添加到Kernel.php 中的 Web 中间件组。它检查 cookie 并设置语言环境,并应重定向到正确的语言环境前缀。如果没有设置 cookie,那么我们会获取用户的地理位置并进行设置。

public function handle($request, Closure $next)
{
    // Get requested url
    $segments = collect($request->segments());

    if ($segments->count() && Arr::exists(config('app.allowed_locales'), $segments[0])) {
        $segments->shift();
    }

    $locale = Cookie::get('locale');

    if ($locale ?? false) {
        // Set the app locale.
        App::setLocale($locale);

        if ($locale != 'en') {
            $segments->prepend($locale);
            return redirect()->to($segments->implode('/'));
        }
    } else {
        // Check for geo here and set it.
    }

    return $next($request);
}

Middleware/RedirectLocalization.php - 此中间件仅在路由组上设置为前缀。它检查是否允许传递的语言环境并设置语言环境和 cookie。这是在Kernel.php 的$routeMiddleware 数组中设置的

public function handle($request, Closure $next)
{
    $locale = $request->segment(1);

    if (Arr::exists(config('app.allowed_locales'), $locale)) {
        // Set the app locale.
        App::setLocale($locale);

        // Save app locale in a Cookie.
        Cookie::queue(Cookie::make('locale', $locale, 525600));
    }

    return $next($request);
}

Controllers/SetLocaleController.php - 在这里可以通过网站上的菜单手动设置区域设置。

public function __invoke($locale, Request $request)
{
    $redirectUrl = parse_url(url()->previous());
    $segments = Str::of($redirectUrl['path'])->trim('/')->explode('/');

    if (Arr::exists(config('app.allowed_locales'), $segments[0])) {
        $segments->shift();
    }

    if (Arr::exists(config('app.allowed_locales'), $locale)) {
        // Set the app locale.
        App::setLocale($locale);

        // Save app locale in a Cookie.
        Cookie::queue(Cookie::make('locale', $locale, 525600));

        // Add locale to segments for redirect.
        if ($locale != 'en') {
            $segments->prepend($locale);
        }
    } else {
        // Set locale to current locale.
        App::setLocale(config('app.fallback_locale'));
    }

    // Redirect back
    return redirect()->to($segments->implode('/'));
}

Controllers/ReaderController.php - 这里没有什么特别之处,但我想添加它来解释忘记.prefix 中间件。如果我不添加 forget.prefix 中间件,则 $reader 参数将成为语言环境。

public function show($reader, Request $request)
{
    $reader = Reader::find($reader);

    return view('readers.show', [
        'reader' => $reader
    ]);
}

Middleware/ForgetPrefix.php - 这个中间件移除了前缀,这样我们就可以访问控制器方法中的参数,而无需在控制器中的方法中添加 $locale 参数。

public function handle($request, Closure $next)
{
    $request->route()->forgetParameter('locale');
    
    return $next($request);
}

所以我的问题是,如果已在 cookie 中设置了区域设置,我该如何设置 URL 前缀而不会出现太多重定向错误?

【问题讨论】:

    标签: laravel localization middleware


    【解决方案1】:

    所以我发现我的问题来自将Middleware/Localization.php 添加到网络中间件组。我在Kernel.php 中将此中间件添加到$routeMiddleware。相反,我只将Middleware/Localization.php 添加到默认语言环境路由中。

    我更新的web/routes.php

    Route::group(['middleware' => 'localization'], function () {
        Route::get('/', 'HomeController@index')->name('home');
        Route::get('/reader/{identifier}', 'ReaderController@show')->name('reader');
    });
    
    Route::group(['prefix' => '{locale?}', 'where' => ['locale' => implode('|', array_keys(config('app.allowed_locales')))], 'middleware' => 'redirect.localization'], function () {
        Route::get('/', 'HomeController@index')->name('home');
    
        Route::group(['middleware' => 'forget.prefix'], function () {
            Route::get('/reader/{identifier}', 'ReaderController@show')->name('reader');
        });
    });
    
    // Switch Locale route
    Route::get('/locale/{locale}', SetLocaleController::class)->name('set.locale');
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-18
      • 1970-01-01
      • 1970-01-01
      • 2021-08-23
      • 1970-01-01
      • 2019-03-09
      • 2016-06-18
      • 2016-08-12
      相关资源
      最近更新 更多