htaccess 结构,什么放在哪里

htaccess 结构,什么放在哪里

我只是想知道我的 htaccess 结构是否正确,我找不到有关在哪里将内容放入 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里面还有很多s 和RewriteCond。一切似乎都运行良好。我有两个问题:

  1. 其中还有其他东西需要移到<ifmodule>块内吗?
  2. s应该RedirectMatche放在顶部吗?

答案1

这取决于您的使用情况。.htaccess 文件按照您编写行的顺序进行处理。

例子:

如果 中的条件与<IfModule>请求匹配,则RedirectMatch永远不会达到,因为RewriteRule被标记为[L],意思是Last
如果您想让 `RedirectMatch 规则具有更高的优先级,您必须将其上调。如果优先级现在没问题,请保持原样。

关于move inside the IfModule block

<IfModule>指令检查给定的模块是否已加载。

优点:如果由于某种原因模块未加载,Apache 仍将启动而不会产生错误。
缺点:由于重写不起作用,您的应用程序可能无法运行。

您可以直接删除这些<IfModule>指令,这样 Apache 启动时您就能立即检测到缺少模块的问题。当然,在这种情况下什么都行不通,因为 Apache 不会启动。

服务器如何运行完全由你决定。

移动AddOutputFilterByType(或其他)指令在 内<IfModule mod_rewrite.c>没有任何意义,因为它们不依赖于该模块。
用它们自己的模块包围它们会更有意义,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>块中正确地使用它了。

答案2

您的指令顺序看起来不错。但是,在同一上下文中混合使用 mod_rewrite ( RewriteRule) 和 mod_alias ( ) 指令通常不是一个好主意。解释如下...RedirectMatch

使用 Apache 配置文件,不同的 Apache 模块(mod_rewrite、mod_alias、mod_expires、mod_access_compat/mod_authz_host 等)将独立处理,而不管配置文件中指令的明显顺序如何。但在每个模块中,指令通常是自上而下处理的(正如您所期望的那样)。

如果所有指令都是自上而下处理的,那么RedirectMatch最后的指令可能永远不会得到处理,因为位于其前面的 mod_rewrite“前端控制器”会将所有不存在文件的请求重写为。因此,最后的index.phpmod_alias指令只是RedirectMatch可靠地因为模块独立执行,所以处理起来很麻烦。但是,mod_rewrite 无论如何都会在 mod_alias 之前执行,因此请求可能index.php在重定向发生之前被重写(RedirectMatch在原始请求 URL 上工作,因此这里没问题)。

  1. es应该RedirectMatch放在顶部吗?

在内部重写(您的 mod_rewrite 前端控制器)之前进行外部重定向会更合乎逻辑。但是,由于您使用 mod_alias 进行重定向,因此它们无论如何都会执行。

但是,正如我在开篇段落中提到的那样,“在同一个上下文中混合使用 mod_rewrite( RewriteRule) 和 mod_alias( RedirectMatch) 指令通常不是一个好主意。” - 这是因为您可能会遇到意外冲突。这取决于您正在执行的操作,但是如果您同时拥有与请求的 URL 匹配的RewriteRuleRedirectMatch指令,那么执行哪个指令就不一定很明显了(这是独立的指令顺序)。因此,最好将 mod_alias 转换RedirectMatch为 mod_rewriteRewriteRule指令。如果这样做,那么RewriteRule指令显然必须现有的 mod_rewrite 字体控制器,否则它们可能永远不会执行。

其中还有其他东西需要移到<ifmodule>块内吗?

实际上,您根本不需要这个<IfModule>块。只有当您的应用程序设计为无需 mod_rewrite 即可工作时,才需要这个块。但我怀疑情况并非如此。例如,WordPress 使用<IfModule>包装器,因为它可以在没有 mod_rewrite 的情况下正常工作(您只是无法获得如此漂亮的“漂亮”URL)。如果您使用<IfModule>包装器并且未安装 mod_rewrite,那么这将默默失败。删除包装<IfModule>器,您会得到一个致命错误 - 该错误发生在系统上线之前,您可以轻松修复它!

但是,使用<IfModule>块的正当理由是,如果您有一个模块依赖于另一个模块的启用。例如,您想要设置Header(with mod_headers),条件是 URL 已使用 mod_rewrite 重写。在这种情况下,您可以将Header指令包含在包装器中<IfModule mod_rewrite.c>。但是,这些情况相当罕见。


关于多个RewriteEngine指令。正如 Gerald 所说,您只需要一个。将其放在文件顶部更合乎逻辑(或者与 mod_rewrite 指令块一起放置一次 - 如果它们位于文件下方的简洁块中)。

然而,这是一个自上而下执行(在模块内)出现问题的例子(这就是为什么我只说“一般来说处理自上而下”)。您可以将RewriteEngine On指令任何地方在配置文件中,它仍然有效 - 如果你愿意,你可以把它放在最后(但这样很混乱)!如果你有多个RewriteEngine指令,那么文件中的最后一个指令将获胜并控制整个文件(当我说“文件”时,严格来说,我的意思是“上下文”)。您无法在整个文件中打开/关闭 mod_rewrite。它对整个文件都是打开或关闭的。这也意味着您可以快速禁用全部只需在文件的最后一行放置一个RewriteEngine Off指令即可 - 您无需注释掉这些指令。(同样适用于指令RewriteBase。)

相关内容