Loading the specific page on Browser Refresh. SPA

2019-05-25 02:11发布

I am creating a new Web API and Angular application. I want to know how we can handle routes on server side. Everything is working fine. I am using ui-router for routing, when i refresh browser that its giving me.

HTTP Error 404.0 - Not Found

I want to know how we can handle this.

Code for 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'
})

The view is loading fine as per the configuration, but when the URL is localhost:1235/register, it's loading fine first time but when I hit the refresh button I get 404 error.

2条回答
smile是对你的礼貌
2楼-- · 2019-05-25 02:41

Here's another way to reroute 404's to your SPA:

 <system.webServer>
    <httpErrors errorMode="Custom">
      <remove statusCode="404" subStatusCode="-1"/>
      <error statusCode="404" prefixLanguageFilePath="" path="/spa-location.html" responseMode="ExecuteURL"/>
    </httpErrors>
 </system.webServer>
查看更多
倾城 Initia
3楼-- · 2019-05-25 02:42

This is occurring because you are using HTML5Mode = true in your Angular Application. Angular uses "hash" (/#register) routes to handle it's routing by default, in order to ensure that the browser does not perform a page reload from the server.

Using HTML5Mode, you can suppress the #, but at a cost. The browser must be HTML5 compliant, because HTML5Mode uses HTML Push State (HistoryAPI).

Also, your server must be configured to handle requests for routes which may exist in Angular but do not exist on the server. When you directly load a page, either by typing it in or by using refresh, a request is sent to the server, with a URL that the server may not know how to handle. Your server should be configured to return your Index.html page for any routes it does not expressly handle. This configuration varies per server.

Given you stated you are using IIS to host your site, something like the following would be necessary:

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>

Essentially, for all routes (.*), if the request is not a file or a directory, rewrite the url to return the base URL /.

This can also be done in code, something similar to this:

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 );
}

There are a few other caveats here:

  1. Each platform handles rewrites differently. In the case of IIS, the URL is rewritten, and the remainder of the route is lost. i.e. for localhost:1235/register, you will actually load localhost:1235/, and Angular will never receive the /register route. Essentially, all routes not known by IIS will return your app entry point.

  2. You can set up multiple entry points to your app, but any in-memory references to variables, settings, etc. will be lost when moving from one entry point to another.

Given these two points, you should always consider any external URLs to be a fresh copy of your Angular application, and handle them accordingly.

查看更多
登录 后发表回答