我只是想知道我的htaccess结构是否正确,我无法find关于在htaccess文件中放置东西的更多信息,所以我只是把它扔在一起。 但是不想在这里粘贴整个htaccess,我的htaccess的总结如下:
Options +FollowSymlinks RewriteEngine On order allow,deny deny from {IP} allow from all #Prevent directory listings Options All -Indexes # compress text, html, javascript, css, xml: AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/xml AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE application/xml AddOutputFilterByType DEFLATE application/xhtml+xml AddOutputFilterByType DEFLATE application/rss+xml AddOutputFilterByType DEFLATE application/javascript AddOutputFilterByType DEFLATE application/x-javascript ErrorDocument 403 /foo/bar/403.html <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC] RewriteRule ^(.*)$ https://%1/$1 [R=301,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /index.php [L] </IfModule> # Redirects RedirectMatch 301 (?i)^/some-fancy-url/?$ /foo/bar/page.php
那里有更多的RedirectMatch
和RewriteCond
。 这一切似乎工作正常。 我有两个问题:
<ifmodule>
块中移动? RedirectMatche
应该位于顶部吗? 这取决于你的用例。 .htaccess文件按照您写入行的顺序进行处理。
例:
如果<IfModule>
中的条件匹配请求,则RedirectMatch
永远不会到达,因为RewriteRule
标记为[L]
,意思是Last
。
如果您希望“RedirectMatch”规则具有更高的优先级,则必须将其向上移动。 如果现在的优先顺序是好的,请保持原样。
关于move inside the IfModule block
的move inside the IfModule block
:
<IfModule>
指令检查给定的模块是否被加载。
上行:如果模块由于某种原因未加载,Apache仍然会启动而不会产生错误。
下行:您的应用程序可能无法正常工作,因为重写不起作用。
您可以删除<IfModule>
指令,以便在Apache启动时立即检测缺失模块的问题。 当然,在这种情况下,什么都不会起作用,因为Apache不会启动。
这取决于你如何要服务器的行为。
移动<IfModule mod_rewrite.c>
中的AddOutputFilterByType
(或其他)指令没有任何意义,因为它们不依赖于该模块。
用它们自己的模块mod_deflate
包围它们会更有意义:
<IfModule mod_deflate.c> AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/xml # ... and so on </IfModule>
我唯一会改变你的文件是省略第一个RewriteEngine On
在线。 只需要一次,而且你的<IfModule>
块中已经有了它。
您的指令的顺序看起来不错。 但是,在相同的上下文中混合使用mod_rewrite( RewriteRule
)和mod_alias( RedirectMatch
)指令通常不是一个好主意。 下面的解释…
使用Apacheconfiguration文件,无论configuration文件中指令的顺序如何,都可以独立处理不同的Apache模块(mod_rewrite,mod_alias,mod_expires,mod_access_compat / mod_authz_host等)。 但是在每个模块中,指令通常是自顶向下处理的(就像你期望的那样)。
如果指令全部自上而下处理,那么最终的RedirectMatch
指令可能永远不会得到处理,因为前面的mod_rewrite“前端控制器”将所有不存在的文件的请求重写为index.php
。 所以,最后的mod_alias RedirectMatch
指令只能被可靠地处理,因为这些模块是独立执行的。 然而,mod_rewrite在mod_alias之前执行,因此在redirect发生之前( RedirectMatch
在原始请求URL上工作,所以你可以在这里),请求可能被重写为index.php
。
RedirectMatch
应该位于顶部吗?
在内部重写之前使用外部redirect(您的mod_rewrite前端控制器)会更合乎逻辑。 但是,由于您正在使用mod_alias作为redirect,所以它们仍然执行。
但是,正如我在开篇中提到的,“在同一个上下文中混合使用mod_rewrite( RewriteRule
)和mod_alias( RedirectMatch
)指令通常不是一个好主意。 – 这是因为你可以得到意想不到的冲突。 这取决于你在做什么,但是如果你有两个RewriteRule
和RedirectMatch
指令,它们都与请求的URL相匹配,那么执行(不依赖于指令的顺序)并不一定是明显的。 由于这个原因,最好把mod_alias RedirectMatch
转换成mod_rewrite RewriteRule
指令。 如果你这样做,那么RewriteRule
指令显然必须在现有的mod_rewrite字体控制器之前,否则它们可能永远不会执行。
那里的其他东西是否需要在
<ifmodule>
块中移动?
这里根本不需要<IfModule>
块。 这只有在您的应用程序被devise为不使用mod_rewrite的情况下才需要。 我怀疑是这样。 例如。 WordPress使用了一个<IfModule>
包装器,因为它可以在没有mod_rewrite的情况下正常工作(你只是没有得到如此漂亮的“漂亮”URL)。 如果你使用<IfModule>
包装,mod_rewrite没有安装,那么这只是失败的默默。 删除<IfModule>
包装,你会得到一个致命的错误 – 这发生在系统上线之前,你可以很容易地修复它!
但是,使用<IfModule>
块的有效原因是,如果有一个模块依赖于另一个被启用。 例如。 你想设置一个Header
(带有mod_headers),条件是URL是用mod_rewrite重写的。 在这种情况下,您可以在<IfModule mod_rewrite.c>
包装器中包含Header
指令。 但是,这些情况相当罕见。
关于多个RewriteEngine
指令。 正如杰拉尔德已经说过的,你只需要一个。 把它放在你的文件的顶部(或者用mod_rewrite指令块 – 如果它们位于文件的后面的简洁块中)则更为合理。
但是,这是自顶向下执行(模块内)种类的一个例子(这就是为什么我只说“ 通常处理自顶向下”的原因)。 你可以在configuration文件的任何位置放置RewriteEngine On
指令,它仍然可以工作 – 如果你想要的话,你可以把它放在最后(但这是令人困惑的)! 如果你有多个RewriteEngine
指令,那么文件中的最后一个指令胜出并控制整个文件 (当我说“文件”时,严格来说我的意思是“上下文”)。 整个文件都不能打开/closuresmod_rewrite。 整个文件的开启或closures。 这也意味着,只需在文件的最后一行放置一个RewriteEngine Off
指令,就可以快速禁用所有 mod_rewrite指令 – 不需要注释掉指令。 (同样的事情适用于RewriteBase
指令。)