3

我的 PHP 项目中有一个前端控制器。这是代码;

.htaccess文件

<IfModule mod_rewrite.c>
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule .* index.php [PT,L]
</IfModule>

index.php文件

<?php
list($url) = explode('?', $_SERVER['REQUEST_URI']);
$url = trim(trim($url), '/');

if(!file_exists('pages/'.$url.'.php')
    header('Location: 404.html');

require_once 'inc/head.php';
require_once 'pages/'.$url.'.php';
require_once 'inc/foot.php';
?>

我假设每个请求的 URL 都必须通过 index.php 文件。但如果 URL 服务器中有一个\(如 %5C),则答案是“未找到”。

问题;

  • 为什么字符有例外\?有没有这样的角色?
  • \使 Apache 搜索文件的常用字符是什么?为什么不直接忽略?
  • Apache 在哪里查找但未找到该文件?

注意:我的系统是带有 Apache 2.2.21 和 PHP 5.3.10 的 Windows。注意2:这只是一个示例代码,所以不提供更好的方法。

4

1 回答 1

2

上面的评论已经说过了:

在 Windows\上是路径分隔符 所以'http://localhost/\' 在 windows 系统上的请求将被 捕获RewriteCond %{REQUEST_FILENAME} -d,只是你的文档根目录,它是一个目录。

您已经反转了条件 d ( !-d) 所以 apache 不执行重写规则而是查找不存在的默认索引文件,您得到 404

删除条件“不是现有目录”或将 index.php 添加到默认值列表

编辑:

我写的故事有这样一个似是而非的特点,以至于我自己都相信了 :) 事实上,这甚至不是 Windows,而是 Apache 特定的。

由于security leak in CGIApache 多年前将其作为修复程序引入。当您在请求 URL 中404 Not Found传递%5C (backslash)或传递时,它不会处理请求,而是立即返回一个, 。%2F (slash)

我能够在Apache 2.2.14.

如果您不使用CGI(例如 Perl 网站),您可以安全地禁用此“安全修复”:

AllowEncodedSlashes On

这是在 Apache 2.0.46 中引入的,请参阅文档,设置此变量在我的中不起作用.htaccess,我不得不将它放入vhost configrestart the apache服务器中。

于 2012-12-01T16:04:00.593 回答