在旧的 Apache 托管中,我们有以下.htaccess
文件public_html/adm
:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /adm/index.php [L]
</IfModule>
如果路径不存在,这应该会将adm
子目录后的每个 URL 重定向到文件。并且工作正常。/adm/index.php
然后我将该网站迁移到 IIS (v8.5),并使用“导入规则...”工具,我尝试实现相同的效果,但起初它会干扰路径下的其他 URL /adm
。为了解决这个问题,我.htaccess
稍微更改了原始文件,如下所示:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond adm/%{REQUEST_FILENAME} !-f
RewriteCond adm/%{REQUEST_FILENAME} !-d
RewriteRule adm/. /adm/index.php [L]
</IfModule>
生成的IIS规则如下:
<rewrite>
<rules>
<rule name="Imported Rule 1" enabled="true" stopProcessing="true">
<match url="adm/." ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="adm/{REQUEST_FILENAME}" matchType="IsFile" pattern="" ignoreCase="true" negate="true" />
<add input="adm/{REQUEST_FILENAME}" matchType="IsDirectory" pattern="" ignoreCase="true" negate="true" />
</conditions>
<action type="Rewrite" url="/adm/index.php" />
</rule>
</rules>
</rewrite>
起初它似乎有效(1),但我很快注意到有效路径也被重定向了(2)。如何才能让它正常工作?
http://example.com/aaaa
返回 404 错误,并http://example.com/adm/aaaa
返回内容http://example.com/adm/index.php
(这是预期的)。http://example.com/adm/images/logo.png
,这是有效路径,返回index.php文件的内容(这是错误的)。
谢谢。
答案1
您的正则表达式不正确。它不匹配/
结果adm/.
返回与 匹配的结果adm/i
。因此,假设该文件不存在是正确的。
你的正则表达式应该是:adm/.*
在 IIS GUI 中创建规则时,点击Test Pattern
该Match URL
部分中的按钮即可查看结果。
答案2
匹配条件未得到满足。这是由于adm/
在条件前面(错误地)添加了 。
的价值REQUEST_FILENAME
服务器变量是文件系统中请求的文件(或目录)的完整路径。在我的特定测试案例中:
请求 URL: http://example.com/adm/images/logo.png
{请求文件名}:F:\IIS\example.com\adm\assets\img\logo.png
出于显而易见的原因,adm/
在该值前面附加内容将使其成为无效的文件系统路径,因此,即使对于有效的文件/目录,重写规则也会被强制执行。解决方案很简单:
即使出于完美主义,过滤模式也可以更新为有效的正则表达式语法,因为仅前面的步骤就足以解决当前的问题。
更新web.config
文件的规则如下。
<rewrite>
<rules>
<rule name="Imported Rule 1" enabled="true" stopProcessing="true">
<match url="(adm\/).*" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" pattern="" ignoreCase="true" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" pattern="" ignoreCase="true" negate="true" />
</conditions>
<action type="Rewrite" url="/adm/index.php" />
</rule>
</rules>
</rewrite>