子应用程序上的IIS URL重定向保持反应SPA

时间:2017-12-11 16:39:08

标签: reactjs iis url-rewriting

我在IIS中托管的现有ASP.Net MVC正在使用react SPA进行扩展/替换,该SPA必须位于应用程序的IIS中的站点下。

这已经完成,因为有多个部署的实例已经为多个客户端出于业务原因无法租用,现有系统是网络表单,并且由于其构建的方式不希望将SPA添加到项目中,决定子应用程序将是部署新功能的最简单方法 - 不希望另一个MVC项目或使WebApi项目服务于静态页面,因为其他客户端相关的自定义必须适应。

SPA与新的WebApi后端进行对话,后端本身就是应用程序下的应用程序。

为了帮助它看起来像这样:

IIS Manager snip

现在一切正常,SPA可以通过普通的href从父应用程序加载,SPA可以很愉快地与WebApi后端进行对话。

我碰到砖墙的是整理IIS Url重写规则,这样如果用户点击SPA中的F5,IIS将返回SPA index.html,然后客户端路由(反应路由器v4)将处理渲染正确的组件。

url重写规则在v5应用程序中定义。

我已经按照this onethis one这样的问题提出建议,如果反应SPA位于网站的根目录下,那么它可以完美运行,但只要我转移到子应用程序我收到的只是一个404响应,表明无法找到完整的Url,例如请求Url时localhost/v5/documents IIS尝试查找不存在的v5 /文档文件/目录。

为了使现有系统脱离等式,我将站点部署到一个新文件夹,其中顶级站点没有内容,反应站点在v5应用程序中,webapi在api文件夹中 - 再次全部工作

我已经为匹配尝试了几种模式,我使用的当前模式是.*/v5/?.*,IIS管理器中的测试模式功能告诉我匹配我期望的URL。 localhost/v5/documents的网址应该匹配,但实际上从不匹配。

我发现this link about configuring angularthis Rick Strahl的帖子涉及创建规则但没有运气。

我目前使用的完整配置是

<rewrite>
  <rules>
    <rule name="Rewrite Text Requests" enabled="true" stopProcessing="true">
      <match url=".*/v5/?.*" />
      <conditions logicalGrouping="MatchAll">
                <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                <add input="{REQUEST_URI}" pattern="/api(.*)$" negate="true" />
                <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
      </conditions>
      <action type="Rewrite" url="{HTTP_HOST}/v5/index.html" logRewrittenUrl="false" />
    </rule>
  </rules>
</rewrite>

我还安装了失败的请求跟踪,但是当我查看日志时,我没有看到为请求触发了url重写,这就是为什么它会尝试查找不存在的文件/目录。

我上传了失败的请求跟踪日志here

我在Windows 10上使用IIS 10.0.15063.0,使用create-react-app创建反应站点(我使用生产版本而不是webpackdevserver进行测试),WebApi项目是.Net Framework 4.7

1 个答案:

答案 0 :(得分:0)

我只是以我能想到的最简单的方式再现了你的情景。

我创建了一个名为MySite的网站,其中包含两个应用程序/ v5和/ v5 / api。

我将以下内容放在v5应用程序的web.config中,因此web.config位于v5的根目录中

<rewrite>
    <rules>
        <rule name="Rewrite Text Requests" enabled="true" stopProcessing="true">
        <match url=".*" />
        <conditions logicalGrouping="MatchAll">
                    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                    <add input="{REQUEST_URI}" pattern="^/v5/api(.*)$" negate="true" />
                    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
        </conditions>
        <action type="Rewrite" url="/v5/index.html" logRewrittenUrl="false" />
        </rule>
    </rules>
</rewrite>

规则的url匹配v5应用程序下的所有内容。如果目标是api应用程序中的文件,目录或任何内容,则使用这些条件退出。

重写操作中不需要主机名。