You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache子目录tree中mod_rewrite重写规则不生效问题排查

问题现象
  • 根目录/var/www/html下仅存储.html页面,放置的.htaccess重写规则运行正常
  • 子目录/var/www/html/tree下存储.php文件,放置了和根目录完全一致的.htaccess文件,但重写规则未生效
  • 预期实现效果:
    • 访问https://example.com/index.html自动跳转至https://example.com/index
    • 访问https://example.com/tree/wallet.php自动跳转至https://example.com/tree/wallet
现有配置

.htaccess 文件内容

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/$ $1.php
RewriteRule ^([^/]+)/([^/]+)/$ /$1/$2.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ /$1/ [R=301,L]

虚拟主机配置(/etc/apache2/sites-available/000-default.conf)

<VirtualHost *:80>
<Directory /var/www/html>
      Options Indexes FollowSymLinks MultiViews
      AllowOverride All
      Require all granted
   </Directory>
<Directory /var/www/html/tree>
      Options Indexes FollowSymLinks MultiViews
      AllowOverride All
      Require all granted
   </Directory>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
故障原因
  1. 目录上下文匹配逻辑错误
    .htaccess在子目录生效时,RewriteRule匹配的请求路径会自动移除当前子目录的路径前缀。原有规则写死了/开头的根路径替换格式,子目录下触发跳转时会直接丢失子目录层级,跳转到根目录下的错误路径。
  2. 规则逻辑和预期不匹配
    现有规则仅实现了「访问带尾斜杠的无后缀路径时,内部映射到对应PHP文件」的效果,完全没有编写「访问带.php/.html后缀的路径时,跳转到无后缀地址」的规则,无法实现需求中的跳转效果。
  3. 缺少重写基准配置
    子目录下的.htaccess未配置RewriteBase参数,相对路径格式的重写目标解析会出现偏差,导致文件定位失败。
  4. 路径匹配规则僵化
    原有规则通过正则写死了最多两级路径的匹配格式,无法适配更深层级的目录结构,也无法自动识别根目录的HTML文件和子目录的PHP文件。
修复方案
  1. 删除/var/www/html/tree目录下的重复.htaccess文件,统一在根目录/var/www/html/.htaccess中编写全目录通用的重写规则,避免多目录下的路径解析冲突。
  2. 将根目录下的.htaccess内容替换为以下通用规则:
RewriteEngine On
RewriteBase /

# 处理带.php后缀的请求,301跳转到无后缀地址
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1 [R=301,L,NE]

# 处理带.html后缀的请求,301跳转到无后缀地址
RewriteCond %{THE_REQUEST} \s/+(.+?)\.html[\s?] [NC]
RewriteRule ^ /%1 [R=301,L,NE]

# 给非文件/非目录的无尾斜杠地址补全尾斜杠
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*[^/])$ /$1/ [R=301,L]

# 内部重写:无后缀带尾斜杠路径优先匹配对应PHP文件(适配tree子目录)
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(.+?)/$ /$1.php [L]

# 内部重写:匹配对应HTML文件(适配根目录HTML页面)
RewriteCond %{DOCUMENT_ROOT}/$1.html -f
RewriteRule ^(.+?)/$ /$1.html [L]
  1. 执行以下操作使配置生效:
  • 执行a2enmod rewrite确认Apache重写模块已启用,若提示模块已启用直接下一步即可
  • 执行systemctl reload apache2重载Apache配置
  • 清除浏览器本地的301跳转缓存(301为永久跳转,本地缓存会导致旧规则持续生效,干扰测试结果)

现有虚拟主机配置中两个目录均已设置AllowOverride All,无需修改。


内容的提问来源于stack exchange,提问作者johnpaperusa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 07:57:26