documentroot定义网站根目录物理起点,重写规则负责请求前动态调整url路径;二者需协同:documentroot须权限正确且可访问,重写规则须置于块内并配齐options、allowoverride和rewriteengine,pattern匹配相对uri路径且需排除真实文件目录。

DocumentRoot 和重写规则(mod_rewrite)要协同工作,关键不是“谁先谁后”,而是明确各自职责:DocumentRoot 定义网站根目录的物理起点,重写规则负责在请求到达前动态调整 URL 路径。两者配合得当,才能让伪静态、统一入口、多端适配等需求稳定运行。
DocumentRoot 必须可访问且权限正确
重写规则再精准,如果 DocumentRoot 目录本身 Apache 无权读取,所有请求都会卡在 403 或 404。配置时务必同步处理:
- 路径末尾不加斜杠,比如
DocumentRoot "/var/www/example.com",而非"/var/www/example.com/" - 配套
<directory></directory>块,并启用Require all granted(Apache 2.4+) - 确认目录属主和权限:Apache 进程用户(如 www-data 或 apache)需有执行(x)权限进入该目录,有读取(r)权限读取文件
重写规则必须放在作用域内才生效
VirtualHost 中的重写规则不会自动继承,也不能只写 RewriteEngine On 在 <virtualhost></virtualhost> 根层级——它必须包裹在 <directory></directory> 块里,并配齐必要选项:
-
Options +FollowSymLinks:多数重写依赖此项,否则可能报 500 错误 -
AllowOverride None(若直接写规则)或AllowOverride All(若同时用 .htaccess) -
RewriteEngine On必须出现在每个需要规则的<directory></directory>内,不能省略
路径匹配写法要符合上下文
在 <directory></directory> 块中写的 RewriteRule,Pattern 部分匹配的是**相对于该目录的 URI 路径**,不是完整 URL:
- 假设
DocumentRoot "/var/www/example.com",且<directory></directory>内写规则 - 用户访问
https://example.com/article/123,Rule 中应写RewriteRule ^article/([0-9]+)$ index.php?id=$1 [L] - 开头不能加
/(即不是^/article/...),否则匹配失败
避免真实文件/目录被误重写
很多入口型框架(如 WordPress、ThinkPHP)靠重写把所有非静态资源导向 index.php,但必须排除真实存在的文件和目录,否则 CSS、JS、图片全 404:
- 在 RewriteRule 前加两行判断:
RewriteCond %{REQUEST_FILENAME} !-fRewriteCond %{REQUEST_FILENAME} !-d - 这样确保只有当请求路径不对应真实文件(!-f)且不对应真实目录(!-d)时,才触发重写











