我的自定义配置文件中包含以下代码。
<Directory "/www">
Options Indexes FollowSymLinks
AllowOverride All
<FilesMatch "\.phps$">
SetHandler application/x-httpd-php-source
</FilesMatch>
ErrorDocument 403 "Please disable proxies to view content."
RewriteEngine On
RewriteRule ^(.*\.php)s$ $1 [H=application/x-httpd-php-source]
RewriteRule ^faq/(\w+)/(\d+)/?$ faq.php?code=$1&num=$2 [NC]
</Directory>
现在,当我浏览到/index.phps
或/some/other/dir/and/file.phps
这样的网页时,我在浏览器中收到404错误,并在apache的错误日志中记录以下内容:
[<date>] [:error] [pid 15154:tid 3024079728] [client <IP>] script 'redirect:/request/get_req.php' not found or unable to stat
[<date>] [:error] [pid 15152:tid 2914974576] [client <IP>] script 'redirect:/index.php' not found or unable to stat
可能导致此问题的原因是什么?另请注意,RewriteRule
的第二个faq/..
工作正常。我在每个目录基础htaccess
文件中还有一些重写规则,并且所有这些规则都正常工作。
我使用的服务器版本是 Apache / 2.4.9(Unix)。
遵循covener和anubhava的建议;我将conf
文件更新为:
<VirtualHost *:80>
DocumentRoot "/www"
<FilesMatch "\.phps$">
SetHandler application/x-httpd-php-source
</FilesMatch>
LogLevel warn
</VirtualHost>
<Directory "/www">
Options Indexes FollowSymLinks
AllowOverride All
RewriteEngine On
# RewriteRule ^(.*\.php)s$ %{DOCUMENT_ROOT}/$1 [H=application/x-httpd-php-source]
# RewriteRule ^/?(.*\.php)s$ %{DOCUMENT_ROOT}/$1 [H=application/x-httpd-php-source]
# RewriteRule ^(.*\.php)s$ $1 [H=application/x-httpd-php-source]
RewriteRule ^(.*\.php)s$ %{DOCUMENT_ROOT}/$1 [H=application/x-httpd-php-source]
RewriteRule ^faq/(\w+)/(\d+)/?$ faq.php?code=$1&num=$2 [NC]
</Directory>
但是php源代码的处理程序仍然记录了同样的错误:
[<date>] [:error] [pid 17586:tid 2956938096] [client <IP>] script 'redirect:/index.php' not found or unable to stat
答案 0 :(得分:2)
你不能进行每个目录的替换并设置Handler(H =),因为mod_rewrite执行每个目录替换的机制需要将处理程序设置为mod_rewrite本身。
per-dir替换有两件事:
因此,通过设置H =,您将吹走1并在您的错误消息中看到apache的核心试图处理“redirect:/ ...”作为文件名。
这是每个目录重写的文档限制,这个H =标志不起作用,但不是它打破了重写:
更改与请求关联的元数据的标志(T =,H =,E =) 在a目录和htaccess上下文中没有任何影响 替换(除了' - ')在同一轮中执行 重写处理。
您应该从&lt; Directory&gt;中提取重写指令上下文并将前导前缀(/?)恢复为第一个参数,并确保第二个参数替换是绝对URL路径而不是相对URL路径。在目录上下文之外,不需要内部重定向,一切都更简单。
e.g。为非per-dir环境安全:
RewriteRule ^(.*\.php)s$ %{DOCUMENT_ROOT}/$1 [H=application/x-httpd-php-source]
RewriteRule ^/faq/(\w+)/(\d+)/?$ /faq.php?code=$1&num=$2 [NC]
在此上下文中,您的URL被映射到文件并设置了处理程序,没有将URL重新引入Apache处理,因为它是一个简单的uri-&gt;文件映射。 我
答案 1 :(得分:2)
要使其正常工作,您需要从<Directory>
容器中取出此代码段并将其放在<VirtualHost>
块中:
<FilesMatch "\.phps$">
SetHandler application/x-httpd-php-source
</FilesMatch>
RewriteEngine On
RewriteRule ^(.*\.php)s$ $1 [H=application/x-httpd-php-source]
它在<VirtualHost>
块中起作用的原因是因为重写发生在早期阶段
apache处理,即per-server
上下文。但是当它发生在per-dir
上下文中时,它会在后期发生并导致请求在替换后重新启动。如果在每个目录上下文中进行替换,则会使用新URL发出新的内部子请求,从而重新开始处理请求阶段。
有关详细信息,请参阅此mod_rewrite tech reference
我的VirtualHost
条目:
<VirtualHost *:80>
<FilesMatch "\.phps$">
SetHandler application/x-httpd-php-source
</FilesMatch>
ErrorDocument 403 "Please disable proxies to view content."
RewriteEngine On
RewriteRule ^([^.]+\.php)s$ $1 [H=application/x-httpd-php-source,NC]
</VirtualHost>