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

在旧的Apache主机中,我们在public_html/adm有以下.htaccess文件:

 <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /adm/index.php [L] </IfModule> 

如果path不存在,这应该将adm /adm/index.php之后的每个urlredirect到/adm/index.php文件。 而且工作得很好。

然后,我把这个网站迁移到了IIS(v8.5),并且使用“Import Rules …”工具,我试图达到同样的效果,但是一开始它和/admpath下的其他网站混淆了。 为了解决这个问题,我改变了原来的.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),但我很快注意到有效的path也被redirect(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 ,这是一个有效的path,返回index.php文件的内容(这是错误的)。

这是来自web.config文件的重写规则的结果。 iis重写规则的视图

谢谢。

你的正则expression式是不正确的。 它不匹配后的整个值/

adm/.的结果adm/. 返回一个匹配的adm/i 。 所以假定文件不存在是正确的。

你是正则expression式应该是: adm/.*

在IIS GUI中创build规则时,请点击“ Match URL部分中的“ Test Patternbutton以查看结果。

比赛条件没有得到满足。 这是由于他们面前的(错误的)join。

REQUEST_FILENAME 服务器variables的值是请求的文件(或目录)在文件系统上的完整path。 在我的具体testing案例中:

请求url: http://example.com/adm/images/logo.png http://example.com/adm/images/logo.png
{REQUEST_FILENAME}F:\IIS\example.com\adm\assets\img\logo.png

出于显而易见的原因,在该值前附加adm/将使其成为无效的文件系统path,结果,即使对于有效的文件/目录,重写规则也将被强制执行。 解决scheme很简单:

正确的重写规则

即使超出完美主义,过滤模式也可以更新为有效的正则expression式语法,因为前一步本身足以解决手头的问题。

新的正则表达式语法

更新了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>