Redirect to default language except for /amp/ URLs

…衆ロ難τιáo~ 提交于 2019-12-20 04:38:30

问题


I'm struggling to solve a redirection but without any success.

I changed the URLs of my site forcing a default language, before it was site.com/help/ and now it's site.com/en/help/. Thanks to help from Stack Overflow I made the redirection, but then I faced a new problem with the AMP pages: site.com/amp/help/ are now redirected to site.com/en/amp/help/ while they are supposed to be site.com/amp/en/help/.

Again, thanks to help on this site, I changed the structure of URLs to site.com/en/help/amp/ (amp always at the end). To achieve this, I had to delete the .php extension I had in some pages and also decided to remove the trailing slash.

I'm now facing two new issues: the 301 redirection to a non .php page and URLs with trailing slashes to a non trailing slash don't work. Below is my htaccess code.

RewriteEngine on

# amp
RewriteRule ^(.*/)?amp/(.+?)/?$ /$1$2/amp [R=301,NC,L]

## redirect to default language (fr)
RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteCond %{REQUEST_URI} !/inc
RewriteCond %{REQUEST_URI} !/ajax/
RewriteCond %{REQUEST_URI} !/img/
RewriteRule ^(?![a-z]{2}(?:[/-]|$))(.*)$ /fr/$1 [R=301,L,NE]

## Unless directory, remove trailing slash
RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)/$ /$1 [R=301,NE,L]

## add trailing slash in front of directories
RewriteCond %{DOCUMENT_ROOT}/$1 -d
RewriteRule ^[a-z]{2}(?:-[a-z]{2})?/(.+)$ /$1/ [L]

# remove .php
RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteCond %{REQUEST_FILENAME} !global.js
RewriteCond %{REQUEST_URI} !/ajax/
RewriteCond %{REQUEST_URI} !results.php
RewriteRule ^(.+)\.php(.*)$ /$1$2 [R=301,NC,NE,L]

## amp pages
RewriteRule ^(.*)/amp$ /$1?amp=1 [NC,QSA,L]

## folders of languages
#RewriteRule ^([a-z]{2}(?:-[a-z]{2})?)/(.*)$ /$2?lang=$1 [QSA,L]
RewriteRule ^([a-z]{2}|[a-z]{2}-[a-z]{2})$ /$2?lang=$1 [QSA,L]
RewriteRule ^([a-z]{2}|[a-z]{2}-[a-z]{2})/(.*)$ /$2?lang=$1 [QSA,L]

## hide .php extention
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_FILENAME} !global.js
RewriteRule ^(.+?)/?$ $1.php [L]

回答1:


Have it this way:

RewriteEngine on

# changed amp URLs
RewriteRule ^(.*/)?amp/(.+?)/?$ /$1$2/amp/ [R=301,NC,L]

## redirect to default language (en)
RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteCond %{REQUEST_URI} !/img/
RewriteRule ^(?![a-z]{2}(?:[/-]|$))(.*)$ /en/$1 [R=301,L,NE]

## Unless directory, remove trailing slash
RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !/amp/$ [NC]
RewriteRule ^(.+)/$ /$1 [R=301,NE,L]

## add trailing slash in front of directories after lang rewrite
RewriteCond %{DOCUMENT_ROOT}/$1 -d
RewriteRule ^[a-z]{2}(?:-[a-z]{2})?/(.+[^/])$ /$0/ [L]

# remove .php
RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteRule ^(.+)\.php$ /$1/ [R=301,NC,NE,L]

## amp pages
RewriteRule ^(.+/)amp/?$ /$1?amp=1 [NC,QSA,L]

## folders of languages
RewriteRule ^([a-z]{2}(?:-[a-z]{2})?)/(.*)$ /$2?lang=$1 [QSA,L]

## hide .php extention
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_FILENAME} !global.js
RewriteRule ^(.+?)/?$ $1.php [L]

Explanation of this trailing slash rule:

## add trailing slash in front of directories after lang rewrite
RewriteCond %{DOCUMENT_ROOT}/$1 -d
RewriteRule ^[a-z]{2}(?:-[a-z]{2})?/(.+[^/])$ /$0/ [L]

Take an example URI: /fr/cart.

In a later rule we remove lang component from URL and pass it as lang=<fr|en> query parameter. Part after lang parameter e.g. /cart doesn't have a trailing slash and if it is a real directory then /cart?lang=fr will be redirected to /cart/?lang=fr by Apache's mod_dir module and your internal URL will be exposed in browser.

So in this current rule we capture part after lang component and check if we don't have a trailing slash and it is a directory then this rule internally rewrites to /fr/cart/ with a trailing slash. Later rule then rewrites it to /cart/?lang=fr and mod_dir doesn't redirect anymore.




回答2:


@anubhava's solution works perfectly well except for one little case: /fr/amp/page.php redirects to /fr/page.php/amp, I had to make some changed to the code and managed to make it work. Below is the updated code with small changes I made:

1- removed some slashes at the end of some rules as I don't need them any more

2- removed this rule RewriteCond %{REQUEST_URI} !/amp/$ [NC]

3- to fix the .php problem, I replaced RewriteRule ^(.+)\.php$ /$1/ [R=301,NC,NE,L] by RewriteRule ^(.+)\.php(.*)$ /$1$2 [R=301,NC,NE,L].

RewriteEngine on

## changed amp URLs
RewriteRule ^(.*/)?amp/(.+?)/?$ /$1$2/amp [R=301,NC,L]

## redirect to default language (en)
RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteCond %{REQUEST_URI} !/img/
RewriteRule ^(?![a-z]{2}(?:[/-]|$))(.*)$ /en/$1 [R=301,L,NE]

## Unless directory, remove trailing slash
RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)/$ /$1 [R=301,NE,L]

## add trailing slash in front of directories
RewriteCond %{DOCUMENT_ROOT}/$1 -d
RewriteRule ^[a-z]{2}(?:-[a-z]{2})?/(.+)$ /$1/ [L]

# remove .php
RewriteCond %{ENV:REDIRECT_STATUS} !200
RewriteRule ^(.+)\.php(.*)$ /$1$2 [R=301,NC,NE,L]

## amp pages
RewriteRule ^(.+/)amp$ /$1?amp=1 [NC,QSA,L]

## folders of languages
RewriteRule ^([a-z]{2}(?:-[a-z]{2})?)/(.*)$ /$2?lang=$1 [QSA,L]

## hide .php extention
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_FILENAME} !global.js
RewriteRule ^(.+?)/?$ $1.php [L]


来源:https://stackoverflow.com/questions/52892995/redirect-to-default-language-except-for-amp-urls

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!