我有以下 RewriteRule,它使得访问 domain.com/somepage/?page=3
的人将被 301 重定向到 domain.com/somepage/3/
:
RewriteCond %{THE_REQUEST} \?page=([0-9]+) [NC]
RewriteRule ^ /somepage/%1/? [R=301,L]
它位于 somepage
目录中的 .htaccess
文件中。
现在,这个工作很好...但是有点麻烦。我有大约十几页已分页的页面,全部都在自己的目录中。我希望能够将 .htaccess 文件复制到每个目录中,而不必担心编辑每个目录。例如,我还希望 domain.com/someotherpage/?page=3
重定向到 domain.com/someotherpage/3/
,但要做到这一点,我需要编辑相应的 .htaccess
文件并将 somepage
部分更改为 someotherpage
。
当我将整个站点复制到不同的服务器时,它也会导致问题。通常,该站点放置在根目录中。但是,当我在本地运行它时,我将整个站点放在名为 dev
的文件夹中。所以现在我必须检查所有 RewriteRules 并将其从 /somepage/%1/
更改为 /dev/somepage/%1
。正如您可能想象的那样,这非常乏味。
那么,有没有一种方法可以更改此设置,使其重定向到的路径相对于 .htaccess
文件,而不是相对于服务器的根目录,以便我可以重用相同的 .htaccess
多次而不更改它,这样我也可以将整个网站移动到 dev
目录中而不需要更改任何内容?
谢谢。
最佳答案
您可以使用单独的规则动态捕获重写基础:
RewriteEngine On
RewriteCond $0#%{REQUEST_URI} ^([^#]*)#(.*)\1$
RewriteRule ^.*$ - [E=BASE:%2]
RewriteCond %{THE_REQUEST} \?page=(\d+) [NC]
RewriteRule ^ %{ENV:BASE}/%1/? [R=301,L]
说明:
- 您可以在
RewriteCond
中使用从RewriteRule
捕获的$0
,因为mod_rewrite
实际上处理规则集向后。它从RewriteRule
中的模式开始,如果匹配,则继续检查一个或多个RewriteCond
。 - 正如您在
RewriteCond
中看到的,LHS(测试字符串)可以使用反向引用变量,例如$1
、$2
或%1
、%2
等,但 RHS 端即条件字符串不能使用 这些$1
、$2
或%1
、%2
变量。 - 在 RHS 条件部分内,我们只能使用内部反向引用,即我们在此条件本身中捕获的组。它们用
\1
、\2
等表示。 - 在
RewriteCond
中,第一个捕获的组是([^#]*)
。它将由内部反向引用“\1”表示。 - 您可以注意到,该规则基本上是通过比较
%{REQUEST_URI}
和$0
来动态查找RewriteBase
。%{REQUEST_URI}
的示例为/directory/foobar.php
,同一示例 URI 的$0
示例为foobar .php
。^([^#]*)#(.*)\1$
将差异放入第二个捕获组%2
或\2
。此处它将使用值/directory/
填充%2
或\2
,稍后在设置环境变量时使用该值%{ ENV:BASE}
即E=BASE:%2
。
关于apache - 使 RewriteRule 可移植/相对于 .htaccess 文件的目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29544180/