当前位置: 首页 > 知识库问答 >
问题:

Laravel定位中间件导致ERR_TOO_MANY_REDIRECTS

左丘弘致
2023-03-14

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

我还可以使用中间件忘记本地化路由上的前缀,这样我就不必用locale参数更新我的方法。

我的问题是设置一个url前缀,如果一个cookie已经设置了一个允许的语言环境在我的中间件。我还想忽略前缀,如果语言环境是'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,那么我们将获取用户的geo并进行设置。

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);
}

此中间件仅在前缀的路由组上设置。它检查传递的区域设置是否允许,并设置区域设置和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::html" target="_blank">setLocale(config('app.fallback_locale'));
    }

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

Controllers/ReaderController.php-这里没有什么不寻常的地方,但我想添加它来解释forget.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前缀,而不会出现过多重定向错误?

共有1个答案

伯俊弼
2023-03-14

因此,我发现我的问题来自将中间件/Localization.php添加到web中间件组。我将这个中间件添加到Kernel.php中的$routeMiddleware。相反,我只将中间件/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');
 类似资料:
  • 我有一个小难题,我正在尝试建立一个登录系统,它使用laravel auth脚手架将普通用户与管理员用户区分开来。 问题是它在中间件中处于无限重定向循环中。 在我按下登录按钮后,它会不断重定向到一条路线,问题是,我如何才能用“laravel方法”或任何其他方法解决这个问题。 这是我的控制器:1。基本家庭控制器: 主管理控制器-入口控制器: 登录控制器(默认的一个从auth scaffolding-由

  • 我正在编写一个国际象棋引擎,最近添加了一个换位表。 在运行一些测试时,我发现尽管搜索仍然返回相同的最佳移动,但移动的值(对最大化玩家来说有多好)是波动的。 这是换位表的正常行为吗?我记得读到转位表会导致搜索不稳定。这是这个意思吗?那么这是我的代码中的正常现象还是严重的错误?

  • 我最近让 STS 将自己从 3.1 更新到 3.5,现在我收到有关 MatchLocator 类的错误。我不确定匹配定位器是什么,但它似乎是 Eclipse 的核心服务。 当我打开STS时,我得到 “初始化Java工具”期间出现内部错误。org/eclipse/JDT/internal/core/search/matching/match locator 打开后,我会为每个applicationC

  • 可能没有多少开发人员像我一样面临这个问题<但是我想分享我已经解决了将近一个月的解决方案 我使用Kubernetes和docker compose,此Webflux服务(容器)设置了内存限制1g

  • 我刚刚安装了laravel 5.2,创建了auth register、login和reset password,但现在我想为我的项目创建一个索引,所有用户(也没有登录)都可以访问。我试图创造 路由::get(“/”,HomeController@home'); 但此视图仅对登录的用户启用。 我的路线 我的家庭控制器 如何创建所有用户都可以访问的视图路径? 谢谢你的帮助!

  • 本文向大家介绍关于扩展 Laravel 默认 Session 中间件导致的 Session 写入失效问题分析,包括了关于扩展 Laravel 默认 Session 中间件导致的 Session 写入失效问题分析的使用技巧和注意事项,需要的朋友参考一下 最近由于项目开发需要,手机客户端和网页端统一使用一套接口,为保证 会话(Session) 能够正常且在各类情况下兼容,我希望能够改变 Session