Apache .htaccess 将规则重写为 IIS FastCGI web.config 规则问题

Apache .htaccess rewrite rule to IIS FastCGI web.config rule problems

所以我有一个自定义的 PHP MVC 框架,它在 Apache 中工作得很好,但很难适应 IIS 10 FastCGI。

这是我的结构:

/website/
- htaccess / web.config
- app folder -> Libraries (Core, Controller, Database), Controllers, Models, Views, Includes, Helpers, etc
- public folder -> css, js, index.php, htaccess / web.config

根 htaccess 如下所示:

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteRule ^$ public/ [L]
  RewriteRule (.*) public/ [L]
</IfModule>

将其翻译成 web.config:

<rules>
  <rule name="Imported Rule 1" stopProcessing="true">
    <match url="^$" />
    <action type="Rewrite" url="public/" />
  </rule>
  <rule name="Imported Rule 2" stopProcessing="true">
    <match url="(.*)" />
    <action type="Rewrite" url="public/{R:1}" />
  </rule>
</rules>

因此,点击 "website" 路由到 "website/public" 效果非常好。

问题出在 Public web.config 上。这是它的 htaccess:

<IfModule mod_rewrite.c>
  Options -Multiviews
  RewriteEngine On
  RewriteBase /website/public
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.+)$ index.php?url= [QSA,L]
</IfModule>

Web.config翻译:

<rule name="Imported Rule 1-1" stopProcessing="true">
  <match url="^(.+)$" ignoreCase="false" />
  <conditions logicalGrouping="MatchAll">
    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
    <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
  </conditions>
  <action type="Rewrite" url="index.php?url={R:1}" appendQueryString="true" />
</rule>

现在我应该可以访问 "website/jobs" 或 "website/jobs/list/0" 了。在 Apache 中工作得很好,但我在 IIS 上得到 404。两天没解决

感谢任何提示!谢谢。

[编辑] 有什么方法可以追踪请求吗?我已经按照 link https://wengier.com/debugging-iis-rewrite-rules/ 尝试在 IIS 中跟踪失败的请求,但 IIS 似乎没有向日志输出任何 404 错误。我的 FRT 设置似乎缺少 "RequestRouting" 和 "Rewrite" 选项,如 link.

中所示

[EDIT2] 两个 web.config 文件之间似乎存在冲突。如果我禁用根 web.config 文件,然后键入 "website/public/jobs"(而不是 "website/jobs",它会起作用。

打开iis select /website/public打开URL Rewrite Import Rules UI,注释掉rewrite base /website/public行并导入其余规则。这将导致重写规则保存到位于该目录的 web.config 文件中。这将为您提供与 apache 上的重写基础相同的行为。

我修好了。这两个web.configs是相互冲突的。所以,我完全放弃了 public/web.config。

我的根 web.config 现在看起来像这样:

<rules>
    <rule name="Imported Rule 1" stopProcessing="true">
        <match url="^$" />
        <action type="Rewrite" url="public/" />
    </rule>
    <rule name="Imported Rule 2" stopProcessing="true">
        <match url="(.*)" />
        <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
        </conditions>
        <action type="Rewrite" url="public/index.php?url={R:1}" appendQueryString="true" />
    </rule>
</rules>