【问题标题】:Rewrite URLs containing subdirectories to script in root将包含子目录的 URL 重写为根目录中的脚本
【发布时间】:2015-07-09 20:36:13
【问题描述】:

我正在尝试重定向页面,将 URL 中表示为子文件夹(“en/”、“de/”...)的语言指示符转换为我可以使用的参数和。 “FR”作为网站的主要语言,没有语言子文件夹。

为了说明这一点:

www.domain/index.html  

应该重定向到

www.domain/index.php?lang=fr

www.domain/en/index.html 

应该重定向到

www.domain/index.php?lang=en

我在我的 .htaccess 文件(位于根目录)中尝试了以下内容:

RewriteEngine On

RewriteRule ^en/index\.html$ /index.php?lang=en [L]   
RewriteRule ^de/index\.html$ /index.php?lang=de [L] 
RewriteRule ^index\.html$ index.php?lang=fr [L]

最后一个按预期工作,但是前两个返回 404。对于第二行(“de 版本”),我得到:

The requested URL /de/index.php was not found on this server.

Apache 记录以下内容:

[Thu Jul 09 13:14:28 2015] [error] [client ::1] script '/Applications/MAMP/htdocs/testsite/de/index.php' not found or unable to stat

前两个规则似乎被服务器完全忽略了,因为在第二行中更改了目标文件名,如下所示:

RewriteRule ^de/index\.html$ /blah.php?lang=de [L]

仍然触发相同的 404 消息,说明缺少 de/index.php 而不是 blah.php;

但是起作用的是将 .htaccess 放在名为“de”的子文件夹中,并从那里指向根文件夹中的 index.php

RewriteRule ^index\.html$ /index.php?lang=de [L]

但这不是一个合适的解决方案,不是吗?

【问题讨论】:

  • 这些真的都是规则吗? error.log 记录哪个路径?启用重写日志记录。
  • 我看到了唯一的问题 - 在第二条规则中添加前导斜杠 RewriteRule ^index\.html$ /index.php?lang=fr [L]
  • /en/index.php - 谁从html更改了扩展名?
  • RewriteRule ^(en)/(index\.html)$ index.php?lang=en [L]
  • @Eric 好的。谁返回 ^/en/ ?我认为htaccess中有更多的行

标签: php .htaccess mod-rewrite


【解决方案1】:

在某些情况下,在规则之前添加这一行会有所帮助:

RewriteBase /

另外,在某些服务器配置中,您需要以^/ 开头,而不仅仅是^。所以规则看起来像这样: RewriteRule ^/en/index.html /index.php?lang=en

这为我解决了一次。

提示:

EN 和 DE 规则都可以写成这样的一条规则:

RewriteRule ^(en|de)/index.html /index.php?lang=$1

这也可以扩展到任意数量的语言环境,只需用| 符号分隔它们。 | 基本上是 OR 运算符。


我已经测试了这些,它们似乎可以满足您的需求:

RewriteRule ^index\.html /index.php?lang=fr [L]

/index.html -> /index.php?lang=fr


RewriteRule ^en/index\.html /index.php?lang=en [L]

/en/index.html -> /index.php?lang=en


RewriteRule ^de/index\.html /index.php?lang=de [L]

/de/index.html -> /index.php?lang=de


另一种限制较少的解决方案看起来是这样的:

RewriteRule ^([a-z]{2})/index.html /index.php?lang=$1

/xx/index.html -> /index.php?lang=xx

这实际上需要任意两个字符并将它们设置在 $1 所在的位置。但这可能不是您真正想要的,这只是一个提示。


附:这是一个测试重写规则的好工具:LINK

【讨论】: