将子目录下的重写规则从 Apache 迁移到 IIS

将子目录下的重写规则从 Apache 迁移到 IIS

在旧的 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)。如何才能让它正常工作?

  1. http://example.com/aaaa返回 404 错误,并http://example.com/adm/aaaa返回内容http://example.com/adm/index.php(这是预期的)。

  2. http://example.com/adm/images/logo.png,这是有效路径,返回index.php文件的内容(这是错误的)。

这是文件重写规则的结果web.config查看 iis 重写规则

谢谢。

答案1

您的正则表达式不正确。它不匹配/

结果adm/.返回与 匹配的结果adm/i。因此,假设该文件不存在是正确的。

你的正则表达式应该是:adm/.*

在 IIS GUI 中创建规则时,点击Test PatternMatch 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>

相关内容