我正在创建一个新的Web API和Angular应用程序。我想知道如何处理服务器端的路由。一切都很好。我正在使用ui-router
进行路由,当我刷新它给我的浏览器时。
HTTP错误404.0 - 未找到
我想知道我们如何处理这个问题。
ui-router的代码
$stateProvider.state('login', {
url: '/',
templateUrl: templatesDirectores.wmAccount + 'login.html',
controller: 'login-controller',
controllerAs: 'vm'
})
.state('register', {
url: '/register',
templateUrl: templatesDirectores.wmAccount + 'register.html',
controller: 'register-controller',
controllerAs: 'vm'
})
.state('forgetPassword', {
url: '/forgetpassword',
templateUrl: templatesDirectores.wmAccount + 'forget-password.html',
controller: 'forget-password-controller',
controllerAs: 'vm'
})
根据配置,视图正常加载,但当网址为localhost:1235/register
时,它首次正常加载,但是当我点击刷新按钮时,我收到404错误。
答案 0 :(得分:4)
这是因为您在Angular应用程序中使用HTML5Mode = true
。角度使用"哈希" (/#register
)路由默认处理它的路由,以确保浏览器不会从服务器执行页面重新加载。
使用HTML5Mode
,您可以取消#
,但需要付费。浏览器必须符合HTML5,因为HTML5Mode使用HTML推送状态(HistoryAPI)。
此外,您的服务器必须配置为处理可能存在于Angular但服务器上不存在的路由请求。当您直接加载页面时,无论是通过输入还是使用刷新,都会向服务器发送一个请求,其中包含服务器可能不知道如何处理的URL。您的服务器应配置为返回您未明确处理的任何路由的Index.html
页面。此配置varies per server。
鉴于您声明您使用IIS来托管您的网站,以下内容将是必要的:
的Web.config:
<system.webServer>
<rewrite>
<rules>
<rule name="Main Rule" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
</system.webServer>
基本上,对于所有路由(.*
),如果请求不是文件或目录,请重写网址以返回基本网址/
。
这也可以在代码中完成,类似于:
的Global.asax:
private const string ROOT_DOCUMENT = "/default.aspx";
protected void Application_BeginRequest( Object sender, EventArgs e )
{
string url = Request.Url.LocalPath;
if ( !System.IO.File.Exists( Context.Server.MapPath( url ) ) )
Context.RewritePath( ROOT_DOCUMENT );
}
此处还有其他一些注意事项:
每个平台都以不同方式处理重写。在IIS的情况下,URL被重写,路由的其余部分将丢失。即对于localhost:1235/register
,您实际上会加载localhost:1235/
,而Angular永远不会收到/register
路由。基本上,IIS未知的所有路由都将返回您的应用程序入口点。
您可以为您的应用设置多个入口点,但是当从一个入口点移动到另一个入口点时,对变量,设置等的任何内存中引用都将丢失。
鉴于这两点,您应始终认为任何外部网址都是Angular应用程序的新副本,并相应地处理它们。
答案 1 :(得分:0)
以下是将404重新路由到SPA的另一种方法:
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404" subStatusCode="-1"/>
<error statusCode="404" prefixLanguageFilePath="" path="/spa-location.html" responseMode="ExecuteURL"/>
</httpErrors>
</system.webServer>