将 RewriteBase 从 htaccess 移动到站点 conf 不起作用

Move RewriteBase from htaccess to site conf doesn't work

这是我原来的 .htaccess 文件。重写规则工作正常:

RewriteEngine On
RewriteBase /backenddev/
RewriteRule ^share/([ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789]{8})$ share.php?token=

但是将 RewriteBase 部分移动到 Apache 的站点 conf 文件并重新启动 Apache 后,它不再起作用了。

只有重写规则的新 .htaccess 文件:

RewriteRule ^share/([ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789]{8})$ share.php?token=

以及 Apache 站点配置文件:

  Alias /backenddev "/var/www/backend_dev/"
  <Directory /var/www/backend_dev/>
    Options FollowSymLinks
    RewriteEngine On
    RewriteBase "/backenddev/"
    AllowOverride All
    
    ...
  </Directory>

当我打开 URL https://<mysite>/backenddev/share/XV6TqNpE 我得到一个 404,网站内容是:

The requested URL /var/www/<mysite>/backend_dev/share.php was not found on this server.

需要重定向到 https://<mysite>/backenddev/share.php?token=XV6TqNpE

知道为什么它不起作用吗?

默认情况下,父配置中定义的 RewriteBase 指令的值不会被子配置继承*1。您需要使用父配置中的 MergeBase 选项明确启用此功能。

例如:

<Directory /var/www/backend_dev/>
  Options FollowSymLinks
  RewriteEngine On
  RewriteBase /backenddev/
  RewriteOptions MergeBase
  AllowOverride All  
  ...
</Directory>

请注意,子配置仍然可以通过设置自己的 RewriteBase 来覆盖它。

*1 这种 默认 行为实际上在 Apache 2.4.4 中发生了变化。在 2.4.0 和 2.4.3 之间,RewriteBase 的值显然默认合并到子配置中。

参考:

MergeBase
With this option, the value of RewriteBase is copied from where it's explicitly defined into any sub-directory or sub-location that doesn't define its own RewriteBase. This was the default behavior in 2.4.0 through 2.4.3, and the flag to restore it is available Apache HTTP Server 2.4.4 and later.

但是请注意,仅此选项不会启用 mod_rewrite 继承 。子 (.htaccess) 配置中的指令仍将完全覆盖父 <Directory> 容器中的指令。 MergeBase 选项仅引用 RewriteBase.

的值

旁白:

RewriteRule ^share/([ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789]{8})$ share.php?token=

这可以“简化”为:

RewriteRule ^share/([a-np-z1-9]{8})$ share.php?token= [NC]

因为字符 ranges.

中只省略了 oO0

然后需要 NC 标志来匹配相应的大写字母。

此外,考虑添加 L 标志,因为您有“其他规则”- 这些可能会被不必要地处理(假设已经没有冲突)。