Angular Visual Studio 网站中的 html5Mode

Angular html5Mode in Visual Studio website

我想在 VS2015 的网站项目中使用 html5Mode。默认页面工作正常,但当我使用在 angular 上定义的路由时,它显示 404 错误。我在 web.config 上添加了以下代码,但它似乎无法正常工作

  <system.webServer>
      <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

我在 angular 上的路线如下:

.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {

    $urlRouterProvider.otherwise("/countries")
    $stateProvider
    .state('mainpage', {
        url: '/countries',
        templateUrl: 'assets/app/templates/countries.html',
        //controller: 'countriesController',
        controller: 'countriesController as cCtrl',
        resolve: {
            officesReso: function (apiCommunicationFactory) {
                return apiCommunicationFactory.Office.get();
            }
        }
    })
    .state('countryDetail', {
        url: '/countries/:office',
        controller: 'countryDetailController as countryDetailCtrl',
        templateUrl: 'assets/app/templates/country.html',
    })

    $locationProvider.html5Mode(true); 
});

我错过了什么吗?我怎样才能让它发挥作用?

原因

您收到 404 是因为请求绕过了应用程序的入口点(因此 angular!),这意味着 Web 服务器将在一个文件夹中寻找服务器指定的默认文档之一不存在。

修复

1) 通过将 <base href="/index.html"> 放在 index.html 文件的 <head> 部分来指定应用程序的入口点。这告诉 angular 相对 URL 应该解析到哪里。

2) 在 web.Config 文件的 <system.webServer> 部分创建重写规则。这会强制 Web 服务器始终访问您的 index.html 文件并允许 angular 路由引擎启动。当然,我们并不 总是 想要访问index.html 每个 http 请求都添加了几个条件来忽略规则。

    <rewrite>
      <rules>
        <rule name="AngularJS 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="api/(.*)" negate="true" />
          </conditions>
          <action type="Rewrite" url="/" />
        </rule>
      </rules>
    </rewrite>

更新 - 回复:重写规则和条件

一定要查看官方文档:URL Rewrite Module Configuration Reference

<match url=".*" />

这是您指定规则何时生效的地方。使用 *.* 它将匹配每个传入请求,并且它将重写 URL 如果条件(如果有)通过...

<conditions logicalGrouping="MatchAll">

这是您指定和分组条件的地方。设置 logicalGrouping="MatchAll" 意味着所有条件都必须计算为真才能重写 URL。

<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />

上面的意思是:确保请求的url没有指向文件。如果您要 link 到您的网络服务器上的文件,您将需要这个。例如,我经常创建 link 到 .ics 文件来创建 public 日历,并且您不想重写(重定向)这些 link,您希望它们命中文件。

<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />

这意味着:确保请求的 url 不指向目录。如果您想列出 Web 服务器上某个目录中的文件,您将需要它。我没有这样做,所以实际上不需要它!

<add input="{REQUEST_URI}" pattern="api/(.*)" negate="true" />

这意味着:确保请求的 url 不以 api/ 开头,即它不是对我的网络 api 的异步调用,因为我所有的 api 调用都以 api/ 开头,我不想将它们重写为 index.html,我想要他们完全按照要求继续并点击我的 api 操作方法。

如果上述任何条件的计算结果为假(即它是一个文件它是一个目录它是一个api调用),然后URL 不会被重写,因为指定了 logicalGrouping="MatchAll"