web-dev-qa-db-ja.com

htaccessには自動リダイレクト+言語+ SEO URLが必要です

私はもっ​​と多くのことを達成しようとしています:

  1. HTTP://はHTTPS://にリダイレクトする必要があります
  2. www.example.comは、クライアントの言語に応じてwww.example.com/en/または/ it /にリダイレクトする必要があります
  3. リンクはwww.example.com?lang=enに解決されるはずです
  4. Index.phpとは異なるすべてのURL? (例:www.example.com/abcd)すべてindex.phpにリダイレクトする必要があります

私は1.3.4を使って作業しました:

RewriteEngine On

RewriteCond %{SERVER_PORT} !^443$ 
RewriteCond %{HTTPS} off 
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]

# RewriteCond %{HTTP:Accept-Language} ^en [NC]
# RewriteRule ^$ https://www.example.com/en/ [L,R=301]
# RewriteCond %{HTTP:Accept-Language} ^it [NC]
# RewriteRule ^$ https://www.example.com/it/ [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(en|it)/(.*) $2?lang=$1 [QSA]
RewriteRule ^([^/]+)$ index.php?op=$1 [L,NS,QSA] index.php

ポイント2を達成しようとしています。コメントを削除すると、リダイレクトループ+エラーになります。

方法はありますか?

2
Mario Bruscella

この答えは記憶から来ています。構文が100%正しい場合は、コメントアウトした4行のコード行を次のように置き換えます。

RewriteCond %{REQUEST_URI} !^/en(.*)$
RewriteCond %{HTTP:Accept-Language} ^en [NC]
RewriteRule ^$ https://www.example.com/en/ [L,R=301]
RewriteCond %{REQUEST_URI} !^/it(.*)$
RewriteCond %{HTTP:Accept-Language} ^it [NC]
RewriteRule ^$ https://www.example.com/it/ [L,R=301]

ここでの目的は、リクエストURI( https://www.example.com の後に続く部分)を確認し、リダイレクト先のURI以外のものであることを確認することです(これにより、リダイレクトループ)。要求URIが一致する場合、ルールは処理されません。

例えば:

RewriteCond %{REQUEST_URI} !^/en(.*)$

..誰かが https://www.example.com/en で始まるURLを入力しなかったことを確認します。その場合、これが確認されます。

RewriteCond %{HTTP:Accept-Language} ^en [NC]

..「en」がaccept-languageヘッダーにあることを確認します。ヘッダーに「en」があり、URLが https://www.example.com/en で始まっていない場合、ユーザーは https:// www。 example.com/ は、このルールを介して https://www.example.com/en/ にリダイレクトされます。

RewriteRule ^$ https://www.example.com/en/ [L,R=301]
1
Mike

書き換えループは、実際にはスクリプトの後半のルールによって引き起こされます。

RewriteRule ^(en|it)/(.*) $2?lang=$1 [QSA]
RewriteRule ^([^/]+)$ index.php?op=$1 [L,NS,QSA] index.php

ユーザーを/en/Accept-Languageルール)にリダイレクトすると、ここの最初のディレクティブはリクエストを?lang=en(URLパスなし)に書き直しますが、2番目のディレクティブは一致しません( URLパスが存在しないため)、index.php(URLパス)に書き換えられません。次に、URL書き換えプロセスが最初からやり直され、ユーザーは/en/に再度リダイレクトされます(URLパスがないため)。

スクリプトに空のopパラメーターを処理できる(提供する必要がある)場合、最後のRewriteRulepattern^([^/]+)$から変更するだけでおそらく解決できます。 ^([^/]*)$に空の文字列をキャッチします。

または、最後から2番目のRewriteRuleに常にURLパスが含まれていることを確認してください。たとえば、次を変更します。

RewriteRule ^(en|it)/(.*) $2?lang=$1 [QSA]

RewriteRule ^(en|it)/(.*) index.php?op=$2&lang=$1 [QSA,L]

ただし、最後のディレクティブが実行していることは実際に複製されます(したがって、Lフラグが追加されます)。

または、言語リダイレクトに条件を含め、lang URLパラメーターが存在しない場合にのみリダイレクトします。例えば:

RewriteCond %{QUERY_STRING} !lang=[a-z]{2}
RewriteCond %{HTTP:Accept-Language} ^(en|it) [NC]
RewriteRule ^$ https://www.example.com/%1/ [L,R=301]

これは、2つのルール(enおよびit)を1つに結合します。

追加するだけで...このタイプの言語検出は一般的ですが、おそらく単純化されすぎており、誤った言語検出を引き起こす可能性があります。優先するために言語が指定されていると想定し(mightではない)、「quality」(q)パラメーターを無視します。 (このテーマに関しては他にも質問がありますが、現時点ではそれらを見つけることができません。)


余談ですが、両方をチェックする必要がありますか...?

RewriteCond %{SERVER_PORT} !^443$ 
RewriteCond %{HTTPS} off
1
MrWhite