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

Apache单.htaccess为不同子域名配置重写规则报500错误求助

故障根因

两种配置触发访问index.php返回500错误的核心原因是重写规则死循环:
当请求被重写规则转发到/index.php后,Apache会发起内部重定向,重新从头加载执行.htaccess中的所有规则,此时请求会再次被匹配、再次转发到index.php,循环次数超过Apache默认的10次上限后,就会直接返回500内部服务器错误。

两个配置还分别存在额外问题:

  • 第一种<If>块写法:博客子域名规则组完全没有添加index.php的重写豁免逻辑,且规则中路径匹配带了开头斜杠,不符合.htaccess上下文的RewriteRule匹配规则(.htaccess中匹配的是相对路径,不带前缀斜杠);同时使用的L标记只能终止当前轮次的重写,无法阻止内部重定向触发的新一轮规则执行。
  • 第二种环境变量写法:Apache在内部重定向时会给已设置的环境变量加上REDIRECT_前缀,第二轮规则执行时原有的SUBDOMAIN变量已经变成REDIRECT_SUBDOMAIN,原有变量判断逻辑直接失效,无法正确命中豁免规则,同样触发循环。
排查步骤
  • 首先查看主机的Apache错误日志,500错误对应的日志条目会明确标注Request exceeded the limit of 10 internal redirects due to probable configuration error,可直接确认循环问题。
  • 梳理重写执行逻辑:.htaccess中的重写规则不会只执行一次,每次内部重定向都会从头重新加载所有规则,必须对最终转发到的入口文件(这里是index.php)做重写豁免。
  • 校验规则匹配逻辑:确认.htaccess上下文的RewriteRule路径不要带开头斜杠,环境变量在重定向后的命名变化,以及重写标记的作用范围。
可用修正方案

优先选择第一种<If>块写法,可读性高、后续新增子域名规则时维护成本低,修正后的配置如下:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /

  # 传递HTTP_AUTHORIZATION头
  RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

  # 主站 example.org 规则
  <If "%{HTTP_HOST} == 'example.org'">
    # 直接请求index.php时终止所有重写,切断循环
    RewriteRule ^index\.php$ - [END]
    # 仅当请求路径不是真实存在的文件、目录时,才转发到index.php
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [END,QSA]
  </If>

  # 博客子域名 blog.example.org 规则
  <If "%{HTTP_HOST} == 'blog.example.org'">
    # 先加index.php重写豁免
    RewriteRule ^index\.php$ - [END]
    
    # 作者页规则:/autor/{author name},去掉路径开头的斜杠适配.htaccess上下文
    RewriteRule ^autor/([^/]+)/?$ /index.php?author_name=$1 [END,QSA]

    # 博客首页规则:/{blog name}
    RewriteRule ^([^/]+)/?$ /index.php?blog=$1 [END,QSA]

    # 文章详情规则:/{blog name}/{year}/{article name}
    RewriteRule ^([^/]+)/([0-9]{4})/([^/]+)/?$ /index.php?blog=$1&year=$2&name=$3 [END,QSA]

    # 子域名根路径规则
    RewriteRule ^$ /index.php?post_type=post [END,QSA]
  </If>
</IfModule>

修正点说明

  • 所有重写规则的L标记替换为END标记:END标记会直接终止整个重写流程,不会触发新一轮的内部重定向,从根源上避免循环问题(Apache 2.4及以上版本支持,目前绝大多数虚拟主机都已满足版本要求)。
  • 给博客子域名规则组补充了index.php的豁免规则,避免重写到入口文件后再次匹配转发规则。
  • 去掉了博客子域名RewriteRule匹配路径开头的斜杠,适配.htaccess上下文的匹配逻辑,确保规则能正常命中。
  • 所有转发规则加上QSA标记,保留原请求自带的查询参数,避免参数丢失。

如果使用的主机Apache版本低于2.4不支持<If>和END标记,可以使用修正后的环境变量写法,核心是给环境变量判断加上REDIRECT_前缀,同时给所有转发规则加上!-f/!-d判断,确保不会重复转发真实存在的index.php文件,不过该写法冗余度高,新增子域名时需要同时修改变量设置和规则判断两处,不推荐优先使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 06:00:54