【问题标题】:Loading the specific page on Browser Refresh. SPA AngularJS在浏览器刷新时加载特定页面。 SPA AngularJS
【发布时间】:2015-07-23 13:18:46
【问题描述】:

我正在创建一个新的 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'
})

根据配置,视图加载正常,但当 URL 为 localhost:1235/register 时,第一次加载正常,但当我点击刷新按钮时出现 404 错误。

【问题讨论】:

  • 请提交更多信息和代码。
  • 您是否偶然在应用程序中使用了HTML5Mode
  • 不要显示伪 url。能否请您更新您的问题,您尝试了哪个确切的 url..
  • 根据您的编辑,您似乎正在使用HTML5Mode。这需要在您的服务器上进行额外设置以确保其正常工作。见github.com/angular-ui/ui-router/wiki/…
  • 您使用的是哪种服务器技术?

标签: angularjs asp.net-web-api single-page-application


【解决方案1】:

这是因为您在 Angular 应用程序中使用了HTML5Mode = true。 Angular 默认使用“散列”(/#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>

本质上,对于所有路由(.*),如果请求不是文件或目录,则重写 url 以返回基本 URL /

这也可以在代码中完成,类​​似于:

全球.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 );
}

这里还有一些其他注意事项:

  1. 每个平台处理重写的方式不同。在 IIS 的情况下,URL 会被重写,并且路由的其余部分会丢失。即对于localhost:1235/register,您实际上将加载localhost:1235/,而Angular 永远不会收到/register 路由。本质上,IIS 不知道的所有路由都将返回您的应用入口点。

  2. 您可以为应用设置多个入口点,但从一个入口点移动到另一个入口点时,对变量、设置等的任何内存引用都将丢失。

鉴于这两点,您应该始终将任何外部 URL 视为 Angular 应用程序的全新副本,并相应地处理它们。

【讨论】:

    【解决方案2】:

    这是将 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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-14
      • 1970-01-01
      • 1970-01-01
      • 2017-03-22
      • 2015-04-07
      • 1970-01-01
      • 2021-09-19
      • 1970-01-01
      相关资源
      最近更新 更多