我有一个LAMP服务器,但我做的网站编码和设计比Apache配置更多。我希望我的问题会很清楚,因为我不太了解.htaccess
文件的语法,而且我的代码主要来源于网络上的教程。
我的网站使用“友好网址”,要启用该功能,我的.htaccess
文件中包含以下代码:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php
但是,我已经在一个子目录下创建了一个包含完整不同HTML的子目录,我希望能够通过这样的URL访问这个子目录:http://www.example.com/subdirectory
。
即使我直接转到http://www.example.com/subdirectory/index.html
,Apache仍会重定向到根目录中的index.php
。
有没有办法可以修改我的.htaccess
文件,以便我的subdirectory
免于重定向?
更新: 经过一些实验,我已经确定正是这条线导致了这个问题(对于那些比我更熟练的人而言,这可能是显而易见的.htaccess文件):
RewriteRule ^(.*) index.php
如果我评论该行,那么子目录中的所有都可以正常工作(当然,网站的其余部分会中断)。如果我把它留在里面,我就会遇到上述问题。
正如下面的答案所示,我尝试将行改为:
RewriteRule !^subdirectory index.php
但这并没有解决问题。我还尝试在子目录中创建一个.htaccess文件,其中包含以下内容:
RewriteEngine On
不幸的是,这没有做任何事。
我对.htaccess语法的理解有限,说我已经拥有的行应该单独保留子目录的内容,但它的表现远比预期的要大得多。
有没有办法可以诊断和修复此行,以便它不会对我子目录的内容起作用?
更新2:
经过一些实验,我发现子目录中的.htaccess文件没有被读取。如果我在其中加入乱码文本,我不会收到任何错误,这似乎表明它甚至没有被访问。
我查找了为什么我的.htaccess文件可能无法被读取的原因,我发现在我的网站的.conf文件中,我需要这个代码:
AllowOverride All
我有那个指令,但子目录中的.htaccess仍未被读取。
我该怎么做以确保正在读取子目录中的.htaccess文件?
我的root .htaccess文件的内容:
# BEGIN Compress text files
<IfModule mod_deflate.c>
<FilesMatch "\.(css|js|x?html?|php)$">
SetOutputFilter DEFLATE
</FilesMatch>
</IfModule>
# END Compress text files
# BEGIN Expire headers
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 seconds"
ExpiresByType image/x-icon "access plus 2592000 seconds"
ExpiresByType image/jpeg "access plus 2592000 seconds"
ExpiresByType image/png "access plus 2592000 seconds"
ExpiresByType image/gif "access plus 2592000 seconds"
ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
ExpiresByType text/css "access plus 604800 seconds"
ExpiresByType text/javascript "access plus 2592000 seconds"
ExpiresByType application/javascript "access plus 2592000 seconds"
ExpiresByType application/x-javascript "access plus 2592000 seconds"
ExpiresByType text/html "access plus 600 seconds"
ExpiresByType application/xhtml+xml "access plus 600 seconds"
</IfModule>
# END Expire headers
# BEGIN Cache-Control Headers
<IfModule mod_headers.c>
<FilesMatch "\.(ico|jpe?g|png|gif|swf)$">
Header set Cache-Control "max-age=2592000, public"
</FilesMatch>
<FilesMatch "\.(css)$">
Header set Cache-Control "max-age=604800, public"
</FilesMatch>
<FilesMatch "\.(js)$">
Header set Cache-Control "max-age=216000, private"
</FilesMatch>
<FilesMatch "\.(x?html?|php)$">
Header set Cache-Control "max-age=600, private, must-revalidate"
</FilesMatch>
</IfModule>
# END Cache-Control Headers
# BEGIN Turn ETags Off
<IfModule mod_headers.c>
Header unset ETag
</IfModule>
FileETag None
# END Turn ETags Off
# BEGIN Remove Last-Modified Header
<IfModule mod_headers.c>
Header unset Last-Modified
</IfModule>
# END Remove Last-Modified Header
# Make all requests pass through index.php to enable "friendly URLs"
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php
# Turn off 'magic quotes'
php_value magic_quotes_gpc off
# Do not allow Perl script hackers, as they are probably just feeding useless Adsense "directory" sites
RewriteBase /
RewriteCond %{HTTP_USER_AGENT} libwww-perl.*
RewriteRule .* - [F,L]
# Filter for most common exploits
RewriteCond %{HTTP_USER_AGENT} libwww-perl [OR]
RewriteCond %{QUERY_STRING} tool25 [OR]
RewriteCond %{QUERY_STRING} cmd.txt [OR]
RewriteCond %{QUERY_STRING} cmd.gif [OR]
RewriteCond %{QUERY_STRING} r57shell [OR]
RewriteCond %{QUERY_STRING} c99 [OR]
# deny most common except .php
<FilesMatch "\.(inc|tpl|h|ihtml|sql|ini|conf|class|bin|spd|theme|module)$">
deny from all
</FilesMatch>
# Disable .htaccess viewing from browser
<Files ~ "^\.ht">
Order allow,deny
Deny from all
Satisfy All
</Files>
此代码位于我的/etc/apche2/apache2.conf
:
# Sets the default security model of the Apache2 HTTPD server. It does
# not allow access to the root filesystem outside of /usr/share and /var/www.
# The former is used by web applications packaged in Debian,
# the latter may be used for local directories served by the web server. If
# your system is serving content from a sub-directory in /srv you must allow
# access here, or in any related virtual host.
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
<Directory /usr/share>
AllowOverride None
Require all granted
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
#<Directory /srv/>
# Options Indexes FollowSymLinks
# AllowOverride None
# Require all granted
#</Directory>
# AccessFileName: The name of the file to look for in each directory
# for additional configuration directives. See also the AllowOverride
# directive.
#
AccessFileName .htaccess
...以下是特定于相关网站的conf文件的内容:
<VirtualHost *:80>
ServerName www.local_example.com
ServerAlias local_example.com
ServerAdmin serveradmin@gmail.com
DocumentRoot /var/www/example.com
<Directory /var/www/example.com/>
Options Indexes FollowSymLinks MultiViews
# pcw AllowOverride None
AllowOverride All
Order allow,deny
allow from all
# This directive allows us to have apache2's default start page
# in /apache2-default/, but still have / go to the right place
# Commented out for Ubuntu
#RedirectMatch ^/$ /apache2-default/
</Directory>
ErrorLog /home/admin/Apache_Logs/local_example.com_error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel debug
CustomLog /home/admin/Apache_Logs/local_example.com_access.log combined
ServerSignature On
</VirtualHost>
答案 0 :(得分:1)
如果/subdirectory
是文件系统上的物理目录而/subdirectory/index.html
是实际文件,则当前指令已包含必要的异常...如果请求的URL映射到,则不应重写URL物理目录或文件。
但是,要明确包含/subdirectory
的例外,您可以执行以下操作:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !^subdirectory index.php
仅处理未启动/subdirectory
的网址。 (并不是在将URL路径与RewriteRule
模式匹配时删除了目录前缀,因此它应该是subdirectory
,而不是/subdirectory
。)
或者,您可以在.htaccess
创建一个额外的/subdirectory/.htaccess
,然后只需启用重写引擎:
# /subdirectory/.htaccess
RewriteEngine On
默认情况下不会继承mod_rewrite指令,因此这应该完全覆盖父.htaccess
文件中的mod_rewrite指令。 (请注意,可能仍会处理来自不同模块的其他指令。)
更新:我在.htaccess
文件中看不到任何会直接导致这些症状的内容,但是,以下内容确实需要修复/整理......
# Do not allow Perl script hackers, as they are probably just feeding useless Adsense "directory" sites
RewriteBase /
RewriteCond %{HTTP_USER_AGENT} libwww-perl.*
RewriteRule .* - [F,L]
# Filter for most common exploits
RewriteCond %{HTTP_USER_AGENT} libwww-perl [OR]
RewriteCond %{QUERY_STRING} tool25 [OR]
RewriteCond %{QUERY_STRING} cmd.txt [OR]
RewriteCond %{QUERY_STRING} cmd.gif [OR]
RewriteCond %{QUERY_STRING} r57shell [OR]
RewriteCond %{QUERY_STRING} c99 [OR]
上面的第二个代码块(&#34;过滤最常见的漏洞和#34;)不完整,不应该有一个尾随的OR
标记(可能会阻止所有人! )。这两个代码块也重复相同的代码,应该组合在一起。 RewriteBase
指令也是多余的,可以删除。以上内容应改写为:
# Do not allow Perl script hackers, as they are probably just feeding useless Adsense "directory" sites
# and Filter for most common exploits
RewriteCond %{HTTP_USER_AGENT} libwww-perl [OR]
RewriteCond %{QUERY_STRING} tool25 [OR]
RewriteCond %{QUERY_STRING} cmd.txt [OR]
RewriteCond %{QUERY_STRING} cmd.gif [OR]
RewriteCond %{QUERY_STRING} r57shell [OR]
RewriteCond %{QUERY_STRING} c99
RewriteRule .* - [F]
F
标志隐含L
,因此此处不需要L
标记。
更新#2:再一次,我在VirtualHost
容器中看不到会导致这些问题的任何内容(尽管如此,老实说,我很难想象甚至会想到什么可能会导致这种行为。)
但是,以下行是可疑的:
Options Indexes FollowSymLinks MultiViews
为什么需要MultiViews
?另外,您需要Indexes
吗?大多数站点将禁用这些选项,因为它们可能会暴露您的文件结构并导致意外行为(除非该行为是故意的)。但是,mod_rewrite需要FollowSymLinks
。
如果不需要这些选项,请尝试删除它们:
选项FollowSymLinks
顺便提一下,也可以使用以下指令在.htaccess中禁用这些选项(请注意,这里的选项前面带有-
):
Options -Indexes -MultiViews