问题
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