htaccess结构,什么去哪里

我只是想知道我的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 

那里有更多的RedirectMatchRewriteCond 。 这一切似乎工作正常。 我有两个问题:

  1. 那里的其他东西是否需要在<ifmodule>块中移动?
  2. RedirectMatche应该位于顶部吗?

这取决于你的用例。 .htaccess文件按照您写入行的顺序进行处理。

例:

如果<IfModule>中的条件匹配请求,则RedirectMatch永远不会到达,因为RewriteRule标记为[L] ,意思是Last
如果您希望“RedirectMatch”规则具有更高的优先级,则必须将其向上移动。 如果现在的优先顺序是好的,请保持原样。

关于move inside the IfModule blockmove 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

  1. RedirectMatch应该位于顶部吗?

在内部重写之前使用外部redirect(您的mod_rewrite前端控制器)会更合乎逻辑。 但是,由于您正在使用mod_alias作为redirect,所以它们仍然执行。

但是,正如我在开篇中提到的,“在同一个上下文中混合使用mod_rewrite( RewriteRule )和mod_alias( RedirectMatch )指令通常不是一个好主意。 – 这是因为你可以得到意想不到的冲突。 这取决于你在做什么,但是如果你有两个RewriteRuleRedirectMatch指令,它们都与请求的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指令。)