【问题标题】:Page doesn't redirect to the specified page on invalid url页面未重定向到无效 url 上的指定页面
【发布时间】:2014-09-11 18:55:55
【问题描述】:

我有下面的 Angular 函数。

功能:

var App = angular.module('app', ['ui.bootstrap', 'ngRoute', 'ngAnimate']); App.config(['$routeProvider', function($routeProvider) { $routeProvider 。什么时候('/', { 模板网址:'views/dashboard.html' }) .when('/:pages', { 模板网址:函数(路由参数){ 返回 '​​views/' + routeParams.pages + '.html'; } }) .otherwise({redirectTo: '404.html'}) }]);

我有一个侧边栏导航控件。我已经创建了 4 个页面。

所以当我点击这些导航项时,相应的页面会正确打开。

还有一些我还没有创建的页面。但是按照下面的函数。

当我没有不存在的东西时,它必须返回到文件夹根目录中存在的404.html文件。

发生的事情是,我在控制台中没有收到错误,并且地址栏中的 url 反映了最后点击的有效页面。

有人让我知道我在哪里做错了,这种方法对于动态路由是否正确?

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    otherwise() 部分捕获与任何指定路由都不匹配的路径。
    在您的情况下,路由匹配,但模板在指定的 URL 上不可用。
    $routeProvider 对此一无所知,也无能为力。

    您可以做的是以某种方式(见下文)检查模板是否可用,如果不可用,请使用$location 重定向到适当的路径(例如/error/404)。

    为了确定页面是否有效(即其模板可用),您可以尝试访问模板(使用$http)并捕获任何错误(表明没有模板)等。但我没有像这种方法(因为依靠模板的可用性来确定页面的存在/有效性并不是一个很好的实践imo - 例如,在网络或服务器问题等情况下,它很容易导致误导性错误消息)。

    我最喜欢的方法是保留“有效”/现有页面的列表并对其进行检查。如果当前页面应该可用,则照常继续获取模板等。如果没有,则重定向到错误页面。

    上面描述的逻辑可以放在$routeProviderresolve属性中(所以它在控制器被实例化和视图加载之前被执行)。

    例如:

    var app = angular.module(...);
    
    // This should be a constant, so it can
    // get injected into configuration blocks
    app.constant('EXISTING_PAGES', [
      'page1',
      'page2',
      ...
    ]);
    
    app.config(function configRouteProvider($routeProvider, EXISTING_PAGES) {    
      $routeProvider.
        when('/', {
          templateUrl: 'views/dashboard.html'
        }).
        when('/:page', {
          templateUrl: function getPageTemplateUrl(routeParams) {
            return 'views/' + routeParams.page + '.html';
          },
          resolve: {
            exists: function resolveExists($location, $route) {
              // Because this is executed before the instantiation of the 
              // controller and the view is not fully loaded yet, the parameters
              // should be accessed via `$route.current.params`
              if (EXISTING_PAGES.indexOf($route.current.params.page) === -1) {
                // This is not a valid/existing page, 
                // let's redirect to an appropriate error page
                $location.replace();   // Replace the URL in the history
                $location.path('/error/404');
              }
              return true;
            }
          }
        }).
        // This should be a separate route, so we can redirect to it
        when('/error/404', {
          templateUrl: '404.html'
        }).
        otherwise({
          redirectTo: '/error/404'
        });
    });
    

    另请参阅此short demo

    【讨论】:

    • 非常感谢。也很明白。我还有一个疑问。使用我之前的功能,即使我转到一个不存在的网址。我没有被路由到404.html 文件。你能告诉我为什么吗?我在控制台中收到GET : (URL which I specified) 404 - Not found 的错误。
    • 您使用redirectTo 表示 HTML 文件。 redirectTo 用于重定向到路由。你应该改用otherwise({templateUrl: '404.html'})
    • 你是最好的,但我发现当我们在错误页面上时“后退按钮”不起作用,在你的例子中只是在我的工作中不起作用显示“试图多次加载角度”: / 任何解决方案?
    • @SzymonDziewoński:发生这种情况是因为后退按钮请求不存在的 URL,该 URL 重定向回 /error/404。您可以解决此问题,将浏览器历史记录中不存在的 URL 替换为 /error/404。这样,后退按钮将使您返回上一个现有页面。您可以使用$location.replace() 执行此操作。我已经更新了答案和演示。
    • 太好了!我正在寻找什么,我发现 Angular 找不到任何不存在的链接视图,所以它破坏了代码:) 感谢快速回复伙伴 :)
    【解决方案2】:

    否则将在没有其他定义匹配时调用。但是您的 /:pages 定义始终匹配,否则不会被调用。尝试加载模板时,否则定义不会对来自服务器的 404 做出反应。

    为每个页面创建路由定义的最简单解决方案,而不是通用的。例如 .when('/page1', ...) .when('/page2', ...) 等等

    【讨论】:

      【解决方案3】:

      redirectTo 更新 $location,因此您不必指定 .html 而是指定 routeParameter。

      你最好这样做:

      [...]
      .when('/error', { templateUrl: '404.html' })
      .otherwise({redirectTo: '/error'});
      

      【讨论】:

        猜你喜欢
        • 2019-04-27
        • 1970-01-01
        • 2016-05-27
        • 2013-12-28
        • 2012-10-15
        • 1970-01-01
        • 2015-08-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多