【问题标题】:How redirect to default language if not present in URL如果 URL 中不存在如何重定向到默认语言
【发布时间】:2013-10-21 21:04:54
【问题描述】:

我正在使用 Mcamara Laravel/localization (https://github.com/mcamara/laravel-localization),如果用于 SEO 目的的 URL 中不存在默认语言,我想重定向到默认语言。

如果我去 www.mydomain.com,它应该重定向到 www.mydomain.com/en。如果我去 www.mydomain.com/something,它应该重定向到 www.mydomain.com/en/something。

我想重定向以避免与 www.mydomain.com 和 www.mydomain.com/en 重复的内容,因为它们是相同的内容和相同的语言。我不想要两个具有相同内容的 URL。如果您的默认语言是“en”,那么您在 www.mydomain.com 和 www.mydomain.com/en/ 上的内容相同

如何进行此重定向? .htaccess 或路由文件?

我无法配置它。谢谢!

【问题讨论】:

    标签: .htaccess laravel laravel-4


    【解决方案1】:

    我从未使用过 mcamara/laravel-localization 包,但我想您可以创建一个简单的路由来检测 URL 中何时未设置语言并重定向到默认语言。

    类似的东西:

    Route::get('/', function(){
        return Redirect::to(Config::get('app.default_language'));  
    });
    

    但我建议您设置一个 cookie,这样当用户切换到其他语言时,您会保留该语言,如果用户返回主页“/”,您会重定向到该语言而不是默认语言。

    根据 OP 评论更新:

    如果你想重定向所有不包含语言的路由,你需要做类似的事情:

    app/filters.php:

    App::before(function($request){
    
      $params = explode('/', Request::path());
    
      if(count($params) >= 1){
    
        $language = $params[0];
        $languages = Config::get('app.languages'); //Available languages in your app ex.: array('en', 'fr', 'es')
    
        if(!in_array($language, $languages)){
    
          $default_language = Config::get('app.default_language');
    
          return Redirect::to($default_language.'/'.Request::path());
        }
      } 
    });
    

    注意:我没有尝试代码,仅供参考。

    【讨论】:

    • 我想重定向我项目中的所有 url,在 URL 字符串中没有语言,而不仅仅是 '/'
    • 完美!!!我在找这个!我在重定向函数中添加了 301:return Redirect::to($default_language.'/'.Request::path(), 301); support.google.com/webmasters/answer/93633
    【解决方案2】:

    这个答案受到@FR6的启发,他的答案很老,并没有涵盖所有问题,所以我做了另一个实现。

    我用中间件和路由分组处理了这个问题 在 laravel 8.0 中测试

    在您的路由文件中web.php 将所有需要本地化参数的路由分组

    Route::group([
        'prefix' => '{locale}',
        'middleware' => 'setLocale'
    ], function() {
        // put your routes here
        Route::get('/welcome', function(){
           return "Hello";
        });
    });
    // add this so when you call route('...') you don't get the error "parameter 'locale' is not set"
    // this is required because all laravel's default auth routes won't add the 'locale' parameter
    \Illuminate\Support\Facades\URL::defaults(['locale' => app('locale-for-client')]);
    
    // redirect the home page route to a specific locale
    Route::get('/', function () {
        return redirect(app('locale-for-client'));
    });
    

    使用php artisan make:middleware SetLocale创建中间件SetLocale

    在 app\Middleware\SetLocale.php 中,如果在给定的 url 上找不到语言环境,我们将重定向到正确的路由

    public function handle(Request $request, Closure $next)
        {
            $url_lang = $request->segment(1);
            if($url_lang !== 'api') {
                if (!in_array($url_lang, config('app.locales'), true)) {
                    return redirect(app('locale-for-client') . '/' . request()->path());
                }
                app()->setLocale($url_lang);
            }
            return $next($request);
        }
    

    在app\Http\Kernel.php

    中注册中间件
    protected $routeMiddleware = [
            ...
            'setLocale' => \App\Http\Middleware\SetLocale::class,
        ];
    

    在 AppServiceProvider 中,我们将定义备用语言。 在我的实现中,我使用客户端 cookie 和浏览器定义的语言环境来获取客户端语言环境。

        public function register()
        {
             $this->app->singleton('locale-for-client', function(){
                $seg = request()->segment(1);
                if(in_array($seg, config('app.locales'), true))
                {
                    // if the current url already contains a locale return it
                    return $seg;
                }
                if(!empty(request()->cookie('locale')))
                {
                    // if the user's 'locale' cookie is set we want to use it
                    $locale = request()->cookie('locale');
                }else{
                    // most browsers now will send the user's preferred language with the request
                    // so we just read it
                    $locale = request()->server('HTTP_ACCEPT_LANGUAGE');
                    $locale = substr($locale, 0, 2);
                }
                if(in_array($locale, config('app.locales'), true))
                {
                    return $locale;
                }
                // if the cookie or the browser's locale is invalid or unknown we fallback
                return config('app.fallback_locale');
            });
        }
    

    next 想要在 config\app.php

    中设置您的语言环境
        'locales' => ['en', 'ar', 'fr'],
        'locales_text_display' => ['en' => 'English', 'ar' => 'العربية', 'fr' => 'Français'],
        'fallback_locale' => 'en',
    

    可选

    既然您已经设置了应用程序区域设置,现在您可能希望让客户根据需要更改他们的区域设置。

    1. 用php artisan make:controller AppLocaleController创建一个控制器
    2. 在控制器AppLocaleController中创建方法更新
    public function update()
    {
       if(in_array(request('locale'), config('app.locales'), true))
       {
          // using cookie('locale', request('locale')) will encrypt the cookie
          // manually set the cookie
          header("Set-Cookie:locale=".request('locale').";Max-Age=300000;path=/");
          return redirect(url('/'));
       }
       abort(400);
    }
    
    1. 注册控制器路由
    Route::post('/api/setLocale', [\App\Http\Controllers\AppLanguageController::class, 'update'])
        ->name('locale.update');
    

    【讨论】:

    • 应用程序('locale-for-client')是什么意思?为什么你使用这个 if($url_lang !== 'api')?什么是“api”?谢谢
    • 对于第一个问题什么是 app('locale-for-client') :这只是我写的一个全局函数,它的定义(注册)在答案的第 4 个代码块上,这个函数将尝试获取或猜测客户端的区域设置(语言)。您可以阅读该函数的 cmets 了解更多详细信息。
    • 对于第二个问题if($url_lang !== 'api'),我在这里检查 url 的第一段是否有单词 'api'(如mysite.com/api/users/1),如果有,我们想忽略语言环境检查是因为这是一个 api 请求而不是普通的浏览器请求。更多信息请查看laravel api
    • 方法 Illuminate\Routing\ResponseFactory::cookie 不存在。当我将表单帖子发送到路由 /setLocale 时,这会返回我
    • 并且 request()->cookie('locale') 在单例 locale-for-client 中调用时总是返回 null
    猜你喜欢
    • 1970-01-01
    • 2013-12-01
    • 2014-11-27
    • 1970-01-01
    • 1970-01-01
    • 2019-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多