apache - 使 RewriteRule 可移植/相对于 .htaccess 文件的目录

标签 apache .htaccess mod-rewrite redirect

我有以下 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/

相关文章:

apache2 处理子域和 SSL

apache - 升级到 Yosemite - Apache 配置 - 无效命令 'User'

apache tomcat 重定向错误 : worker1 connecting to backend failed

php - 使用 RewriteEngine 时图像未加载?

Python CGI 显示 500 内部服务器错误

php - 使用 mod_rewrite 将 .html 重写为 .php

php - Docker 容器上的应用程序之间的 Curl 连接被拒绝

.htaccess - 为什么这个 .htaccess 重定向不起作用?

php - .htaccess 文件有问题

apache - 使用 mod_rewrite 虚拟 chroot 客户端?