如何让.htaccess的RewriteRule同时实现页面拦截跳转与日志记录?
实现拦截页面展示与日志写入的.htaccess配置方案
完全可以同时实现展示拦截页面和写入日志的需求,以下是两种实用方案:
方案1:PHP脚本处理日志+内部转发展示拦截页
这种方案适合需要自定义日志内容或复杂处理的场景,通过mod_rewrite的内部转发先执行日志脚本,再展示拦截页面:
.htaccess配置
<IfModule mod_rewrite.c> # 内部转发到日志脚本,传递请求URI、客户端IP、用户代理等信息,L标志允许后续规则执行 RewriteRule .* /log.php [L,NE,E=REQUEST_INFO:%{REQUEST_URI}___%{REMOTE_ADDR}___%{HTTP_USER_AGENT}] # 内部转发到拦截页面,END标志终止后续规则处理 RewriteRule .* /permission-denied [END] </IfModule>
log.php脚本示例
<?php // 获取Apache传递的环境变量(注意前缀REDIRECT_) $requestInfo = $_SERVER['REDIRECT_REQUEST_INFO'] ?? ''; // 拼接日志内容,包含时间戳和请求信息 $logContent = date('Y-m-d H:i:s') . ' - ' . $requestInfo . PHP_EOL; // 写入日志文件,确保目录有写入权限,LOCK_EX避免并发写入冲突 file_put_contents('/var/www/html/logs/access_denied.log', $logContent, FILE_APPEND | LOCK_EX); // 无需输出内容,后续规则会自动转发到拦截页面 ?>
注意:如果需要浏览器地址栏显示/permission-denied(外部重定向),可将第二个RewriteRule的END改为R,L,此时log.php仍会在后台执行。
方案2:Apache自定义日志直接记录(无需PHP)
如果仅需记录基础请求信息,可直接用Apache的mod_log_config模块配置,无需额外脚本:
第一步:添加自定义日志规则
在Apache主配置文件或.htaccess中添加(若用.htaccess需确保AllowOverride包含Options或FileInfo):
# 定义日志格式:时间、请求URI、客户端IP、用户代理 LogFormat "%{%Y-%m-%d %H:%M:%S}t %U %a %{User-Agent}i" denied_log # 指定日志文件路径,仅当环境变量DENIED_ACCESS存在时写入 CustomLog "/var/www/html/logs/access_denied.log" denied_log env=DENIED_ACCESS
第二步:修改.htaccess的拦截规则
<IfModule mod_rewrite.c> # 设置环境变量触发日志,同时外部重定向到拦截页面 RewriteRule .* /permission-denied [R,L,E=DENIED_ACCESS:1] </IfModule>
方案选择建议
- 需要复杂日志处理(如解析参数、关联业务数据)→ 选方案1
- 仅需基础请求记录,追求配置简洁高效→ 选方案2
内容的提问来源于stack exchange,提问作者Den4ik
相关产品推荐
相关产品推荐

