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>
所以我有一个自定义的 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>