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"
。
我想在 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"
。