我只是想知道我的 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
。一切似乎都运行良好。我有两个问题:
- 其中还有其他东西需要移到
<ifmodule>
块内吗? - 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.php
mod_alias指令只是RedirectMatch
可靠地因为模块独立执行,所以处理起来很麻烦。但是,mod_rewrite 无论如何都会在 mod_alias 之前执行,因此请求可能index.php
在重定向发生之前被重写(RedirectMatch
在原始请求 URL 上工作,因此这里没问题)。
- es应该
RedirectMatch
放在顶部吗?
在内部重写(您的 mod_rewrite 前端控制器)之前进行外部重定向会更合乎逻辑。但是,由于您使用 mod_alias 进行重定向,因此它们无论如何都会执行。
但是,正如我在开篇段落中提到的那样,“在同一个上下文中混合使用 mod_rewrite( RewriteRule
) 和 mod_alias( RedirectMatch
) 指令通常不是一个好主意。” - 这是因为您可能会遇到意外冲突。这取决于您正在执行的操作,但是如果您同时拥有与请求的 URL 匹配的RewriteRule
和RedirectMatch
指令,那么执行哪个指令就不一定很明显了(这是独立的指令顺序)。因此,最好将 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
。)