【问题标题】:Redirect to default language except for /amp/ URLs重定向到默认语言,/amp/ URL 除外
【发布时间】:2019-04-19 02:57:10
【问题描述】:

我正在努力解决重定向但没有任何成功。

我更改了网站的 URL,强制使用默认语言,之前是 site.com/help/,现在是 site.com/en/help/。感谢 Stack Overflow 的帮助,我进行了重定向,但后来我遇到了 AMP 页面的新问题:site.com/amp/help/ 现在被重定向到 site.com/en/amp/help/,而它们应该是 site.com/amp/en/help/

再次感谢本网站的帮助,我将 URL 的结构更改为 site.com/en/help/amp/(始终位于末尾)。为此,我不得不删除某些页面中的 .php 扩展名,并决定删除尾部斜杠。

我现在面临两个新问题:301 重定向到非 .php 页面和带有尾部斜杠到非尾部斜杠的 URL 不起作用。下面是我的 htaccess 代码。

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]

【问题讨论】:

  • 在根目录中。而且我实际上没有任何amp目录
  • 我们刚刚决定将 /amp 设置为 AMP 页面和所有语言的根目录,您会怎么做?
  • 好的,我想现在换一种方式,你觉得 site.com/en/help/amp/ (amp/) 总是放在最后
  • I4m 只是尝试使用一个简单而单一的约定 :) 所以我会选择我认为最好的 site.com/en/help/amp/ :)
  • 好的,我会这样做的,我会告诉你的 :) thanjs 再次为你提供建议 :)

标签: regex .htaccess url-rewriting


【解决方案1】:

这样吧:

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]

解释这个尾部斜杠规则:

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

以 URI 为例:/fr/cart

在后面的规则中,我们从 URL 中删除 lang 组件并将其作为 lang=<fr|en> 查询参数传递。 lang 参数后的部分,例如/cart 没有尾部斜杠,如果它是真实目录,则 /cart?lang=fr 将被 Apache 的 mod_dir 模块重定向到 /cart/?lang=fr,并且您的内部 URL 将在浏览器中公开。

因此,在当前规则中,我们捕获lang 组件之后的部分并检查我们是否没有尾部斜杠并且它是一个目录,然后此规则在内部重写为带有尾部斜杠的/fr/cart/。随后的规则将其重写为/cart/?lang=fr 并且mod_dir 不再重定向。

【讨论】:

  • 感谢您的代码。我已经尝试过了,但效果不佳:当我转到 site.com/es 时,它会重定向到 .com/en/es :(
  • 现在有一个新问题:如果我输入/en/cart/,它会导致太多时间重定向:/en/cart?lang=en&lang=en&lang=en...当然我清除了浏览器缓存以进行测试
  • 好的,我注意到如果文件夹“购物车”存在(这是我的情况),则会发生太多重定向,但如果我输入/cartt,它会将我很好地重定向到/en/cartt
  • 抱歉,只是忘了更改它:) 并感谢您在编辑后的消息中的解释。现在对我来说更清楚了:)祝你有美好的一天,再次感谢大家
  • 嗨@anubhava,希望你做得很好,很抱歉打扰你,你一直是我的救星,我发布了一个问题,但没有人能给我一个有效的解决方案,你能看看这个帖子:stackoverflow.com/questions/60414527/… 吗?非常感谢
【解决方案2】:

@anubhava 的解决方案运行良好,除了一个小案例:/fr/amp/page.php 重定向到/fr/page.php/amp,我不得不对代码进行一些更改并设法使其工作。以下是我做了一些小改动的更新代码:

1- 删除了一些规则末尾的一些斜线,因为我不再需要它们了

2- 删除这条规则RewriteCond %{REQUEST_URI} !/amp/$ [NC]

3- 为了解决 .php 问题,我将 RewriteRule ^(.+)\.php$ /$1/ [R=301,NC,NE,L] 替换为 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]

【讨论】:

  • 感谢您根据其他人的回答编译一个工作示例,这可能对其他读者有所帮助。但是,这里的一些要点实际上是补充问题,它们不属于答案。您似乎与您的助手进行了评论对话,并提出了一个新问题 - 这是正确的做法。
猜你喜欢
  • 2013-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-31
  • 2014-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多