【问题标题】:Angular ui-router pressing refresh causes 404 errorAngular ui-router 按下刷新会导致 404 错误
【发布时间】:2015-08-04 21:56:08
【问题描述】:

好的,我知道这是一个开放式问题,但是 -

我正在使用 AngularJS 1.4.x 和 ui-router 运行应用程序。在大多数情况下,一切正常且符合预期。我的各个页面使用 ui-sref 进行导航,页面按预期显示,并且显示的 URL 看起来正确。但是,如果我在任何页面上刷新页面 (F5),就会导致发生 404 错误。并且输入 URL 不再有效。

可能涉及的事情:

  • 我打开了$locationProvider.html5Mode(true)标志
  • 我用

    $rootScope.$on('$stateChangeStart', function (event, toState, toParams)

    管理页面访问(身份验证)

  • <base href="/"> 是 在我的 index.html 中,因为没有它 html5Mode() 将无法工作

【问题讨论】:

  • 这有什么更新吗?我有同样的问题。 (仍在使用 Angular 1.6.4)

标签: angularjs angular-ui-router


【解决方案1】:

问:当您刷新页面时,实际发生了什么?

答:您正在通过浏览器向服务器发送 HTTP 请求。 GET /whatever。因此,服务器需要为此请求设置一个路由,该路由以index.html 响应。目前,您收到的是404,因为您的服务器没有与GET /whatever 的请求相匹配的路由。

问:为什么?

答:当您通过浏览器(而不是通过 AJAX)发出请求时,您的浏览器会尝试向您显示响应。前任。如果响应是 JSON,它会显示 JSON。如果它是一个字符串,它会显示一个字符串。如果它是一个 html 页面,它会显示给你。您不能只为任何路线发回模板,因为如果您这样做,它只会在没有其他上下文的情况下呈现该模板。你需要index.html 来加载角度,运行你的控制器,将模板放在它的ui-view 容器中,等等。

(会发生index.html会被发回,UI Router会检查路由,请求templateUrl,运行控制器,然后渲染它。)

问:如何?

A:这取决于 a) 您使用的服务器类型和 b) 您的文件结构。您可能希望在为index.html 提供服务的路径文件的末尾添加某种捕获所有路径。这就是我使用 Node/Express 的方式:

app.get('/*', function(req, res) {
  var url = path.resolve(__dirname + '/../client/index.html');
  res.sendFile(url, null, function(err) {
    if (err) res.status(500).send(err);
    else res.status(200).end();
  });
});

【讨论】:

  • 你说的很有道理。在添加 html5Mode() 标志之前,我的 URL 看起来像这样 (localhost:50086/index.html#/dashboard) 而一旦我添加了标志,它看起来像这样 (localhost:50086/dashboard)。后者是我想要的,但由于某种原因,由于 Index.html 不再是 URL 的一部分,VS IIS 服务器不够精明,无法理解 index.html 是我的默认文档并从那里运行。它寻找一个称为仪表板的文字路径,那里缺少 index.html 页面,只有 404。
  • 很抱歉听到这个消息。将其分为两个问题可能是一个好主意:1)为什么 UI 路由器在刷新时不起作用(这个)和 2)如何添加一个 catch all 路由到发回 index.html 的 VS IIS 服务器.我不知道问题 2 的答案,并且鉴于您对这个问题使用了角度标签,我认为您不会在这里找到它。不过,添加 catch all 路线应该不难。
【解决方案2】:

@Adam Zerner 很好地描述了它。我还设法找到了这些不错的帖子:

AngularJS HTML5 mode reloading the page gives wrong GET request

Page reload fails when using Angular Ui Router with Html5 mode enabled

所以,鉴于问题在于您的服务器的路由配置,您显然可以:

  1. 检查您的.htaccess 设置
  2. 在服务器的路由配置中设置一些捕获所有路由配置

或者简单地说:

  1. 提供您的模板(通过一些简单的通用控制器函数)

这听起来可能与您寻求的动态路由背道而驰,但由于没有其他选项可以更好地解决此问题,这可能是最简单和最优雅的一个。

想一想,在提供的任何其他解决方案中,您仍然需要通过服务器,无论是路由规则还是只是为您的请求提供服务 - 成本大致保持不变,即使存在差异 - 它应该可以忽略不计。

【讨论】:

    【解决方案3】:

    这将是由于您的服务器路由设置不正确,并且没有及时加载 Angular 来处理路由。您需要确保在您的服务器上设置了一个包罗万象的路由,该路由为所有非 api url 调用发送您的索引页面,以便 Angular 有机会加载和管理路由。

    你没有指定你的服务器语言,但在 node/express 中它会是这样的:

    app.use('/*', express.static('./path/to/index.html'));
    

    【讨论】:

    • 我不确定我明白你在说什么。我在 Visual Studio 中创建网站,虽然我没有在网站中使用任何 Microsoft 技术,我只是将它用作我的编辑器。所以所有的页面都是纯 HTML5 和 Angular,而服务器是 IIS Express 或任何 MS 如今所称的。据我所知,它默认配置为运行 index.html。
    • 我没有这种设置的经验,所以我不确定如何给你建议。我所知道的是,我遇到了您所描述的问题,并且一直是由于服务器在 Angular 的 ui-router 有机会接管之前接管了路由,即 Angular 没有及时加载到浏览器中。抱歉,我无法提供更多帮助。