如何使用 IIS 设置 react-router clean URL?

Posted

技术标签:

【中文标题】如何使用 IIS 设置 react-router clean URL?【英文标题】:How do I setup react-router clean URL's with IIS? 【发布时间】:2016-10-10 22:50:05 【问题描述】:

React-Router 通过简单的路由组件让你的 ReactJS 应用成为一个 SPA。部署到 IIS 时,使用 bashHistory 进行设置时一切正常。但是,当我尝试使用 browserHistory 时,IIS 试图返回一个目录,而不是让 React-Router 抓取和解析路由。如何设置 React-Router 以在 IIS 环境中工作?

【问题讨论】:

【参考方案1】:

让 React-Router 与 IIS 一起工作的关键是设置 URL 重写规则。在查看了其他人如何使用 IIS 设置 AngularJS SPA 应用程序后,我提出了以下解决方案。

    在您的服务器上下载并安装URL Rewrite(开发和生产)

    设置规则以捕获任何不是文件和不是目录的 url 路由。或者,您可以否定您希望定期提供的任何实际目录。更多信息可以在这里找到Microsoft's Documentation

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
      <system.webServer>
      <rewrite>
        <rules>
          <rule name="ReactRouter Routes" stopProcessing="true">
            <match url=".*" />
            <conditions logicalGrouping="MatchAll">
              <add input="REQUEST_FILENAME" matchType="IsFile" negate="true" />
              <add input="REQUEST_FILENAME" matchType="IsDirectory" negate="true" />
              <add input="REQUEST_URI" pattern="^/(docs)" negate="true" />
            </conditions>
            <action type="Rewrite" url="index.html" />
          </rule>
        </rules>
      </rewrite>
    </system.webServer>
    </configuration>
    在您的基本 html 页面 (index.html) 中,为您的应用添加一个带有 href 属性的 &lt;base/&gt; 标记。

&lt;base href='/path/to/my/app'/&gt;

【讨论】:

非常感谢。在 IIS 上没有多少 React'ers。这很有帮助。投票赞成! 很高兴您发现它有帮助! IIS 不是我的第一选择,但必要性是所有发明的根源 :) 您在实施此更改时是否看到与您的反应路由器相关的任何此类错误? "警告:使用 自动设置 basename 已弃用,将在下一个主要版本中删除。 的语义与 basename 略有不同。请在选项中显式传递 basename 到 createHistory" 一个重点:在你的react文件夹中创建一个名为“web.config”的文件,其中包含index.html,并粘贴上面的xml作为起点。 太棒了!一个我可以复制和粘贴的答案,它可以工作!注意@Brain2000 评论,这就是我实际所做的,而不是尝试在 IIS 中配置它。【参考方案2】:

只是为任何感兴趣的人建立这个答案。如果您喜欢我并且需要通过脚本部署您的应用程序。以下是创建上述 web 配置所需的 powershell 脚本。

这会在服务器上安装 URL 重写。

    #Install IIS UrlRewrite
    If(Test-Path c:/msi) 
    Invoke-WebRequest 'http://download.microsoft.com/download/C/F/F/CFF3A0B8-99D4-41A2-AE1A-496C08BEB904/WebPlatformInstaller_amd64_en-US.msi' -OutFile c:/msi/WebPlatformInstaller_amd64_en-US.msi
    Start-Process 'c:/msi/WebPlatformInstaller_amd64_en-US.msi' '/qn' -PassThru | Wait-Process
    cd 'C:/Program Files/Microsoft/Web Platform Installer'; .\WebpiCmd.exe /Install /Products:'UrlRewrite2,ARRv3_0' /AcceptEULA /Log:c:/msi/WebpiCmd.log
    
    else 
    New-Item c:/msi -ItemType Directory
    Invoke-WebRequest 'http://download.microsoft.com/download/C/F/F/CFF3A0B8-99D4-41A2-AE1A-496C08BEB904/WebPlatformInstaller_amd64_en-US.msi' -OutFile c:/msi/WebPlatformInstaller_amd64_en-US.msi
    Start-Process 'c:/msi/WebPlatformInstaller_amd64_en-US.msi' '/qn' -PassThru | Wait-Process
    cd 'C:/Program Files/Microsoft/Web Platform Installer'; .\WebpiCmd.exe /Install /Products:'UrlRewrite2,ARRv3_0' /AcceptEULA /Log:c:/msi/WebpiCmd.log
    

这是添加规则的方法。

Add-WebConfigurationProperty -pspath "$IISPath\MyWebsite" -filter "system.webServer/rewrite/rules" -name "." -value @name='Home';stopProcessing='True'
Set-WebConfigurationProperty -pspath "$IISPath\MyWebsite"  -filter "system.webServer/rewrite/rules/rule/match" -name "url" -value ".*"

Add-WebConfiguration -pspath "$IISPath\MyWebsite" -filter "system.webServer/rewrite/rules/rule[@name='Home']/conditions" -value @ input="REQUEST_FILENAME"; matchType="IsFile"; negate="true" 
Add-WebConfiguration -pspath "$IISPath\MyWebsite" -filter "system.webServer/rewrite/rules/rule[@name='Home']/conditions" -value @ input="REQUEST_FILENAME"; matchType="IsDirectory"; negate="true" 
Add-WebConfiguration -pspath "$IISPath\MyWebsite" -filter "system.webServer/rewrite/rules/rule[@name='Home']/conditions" -value @ input="REQUEST_URI"; pattern="^/(docs)"; negate="true" 

Set-WebConfigurationProperty -pspath "$IISPath\MyWebsite"  -filter "system.webServer/rewrite/rules/rule/action" -name "type" -value "Rewrite" 
Set-WebConfigurationProperty -pspath "$IISPath\MyWebsite"  -filter "system.webServer/rewrite/rules/rule/action" -name "url" -value "index.html"

这些脚本可以在本地或通过 Powershell 中的 Invoke-Command 远程执行。

此外,我在使用 React Router 警告和在 index.html 的标头中使用 base 标记时遇到了一些问题。这个链接很有帮助。

https://github.com/ReactTraining/react-router/issues/4006

我基本上将我的 React-Router 包和 History 包更改为 3.x 版,并在我的路由器中设置配置以消除弃用警告。这是我现在的反应路由器。

import  useRouterHistory  from 'react-router'
import  createHistory  from 'history'

const history = useRouterHistory(createHistory)(
basename: '/base-path'
)

ReactDOM.render(
  <Router history=history>
 ....

【讨论】:

规则最好保存在 web.config 文件中,与 react 的应用程序位于同一文件夹中。

以上是关于如何使用 IIS 设置 react-router clean URL?的主要内容,如果未能解决你的问题,请参考以下文章

从reach/router切换到react-router时,如何设置basename?

如何在 react-router 中为 Link 或 IndexLink 的包装元素设置 activeClassName?

在 react-router V4 中,如何以编程方式设置查询字符串参数?

如何在 react-router v4 的根路由上设置可选参数?

ReactJS + React Router:如何从 React-Router 的 <Link> 禁用链接?

React-router:如何将 props 传递给子组件?