角度路由 - 重定向到外部站点?

时间:2013-08-08 16:20:58

标签: javascript angularjs url-routing

在AngularJS路线文件中,可以选择otherwise路线,替换404:

$routeProvider
.when(...)
.otherwise({
    redirectTo: 'my/path'
});

有没有办法做到这一点,否则重定向到不在应用程序中的页面?我试过了

$routeProvider
.when(...)
.otherwise({
    redirectTo: 'http://example.com'
});

但是这个jsut尝试重定向到我的应用程序中的那条路径,这条路径不存在。我所知道的解决方案是在顶级控制器的$scope.$on('$routeChangeStart')中进行手动重定向,但这是很多代码重复(而且很难看)。还有更好的方法吗?

4 个答案:

答案 0 :(得分:6)

对于我的knowledge,这是不可能的,因为routeProvider仅处理内部路由。

你可以做的是

$routeProvider
.when(...)
.otherwise({
    controller: "404Controller",
    template: "<div></div>"
});

然后在控制器中使用window.location.href = 'http://yourExternalSite.com/404.html'

答案 1 :(得分:5)

就我而言,这对我有用:

$routeProvider
.when('/my-path', {
    ...typical settings...
}).
.otherwise({
        redirectTo: function(obj, requestedPath) {
            window.location.href = appConfig.url404;
        }
});

答案 2 :(得分:4)

只需查看angular.js link behaviour - disable deep linking for specific URLs

即可

并使用此

  

目标=#&34; _self&#34;

<a href="link" target="_self" >link</a>

答案 3 :(得分:2)

我不建议在新控制器中使用window.location.href,如其他答案中所指出的那样,因为ngRoute会将历史记录设置为指向不存在的页面(所以当用户点击它时会保持重定向到404页面)。我试过但失败了。

我想在此向您指出另一个SO问题的相关解决方案: https://stackoverflow.com/a/27938693/1863794

我采用了它并应用于您的场景。我不认为在ng-view之外使用MainCtrl这是一个不好的想法,因为它只会被声明一次,除非你有ng-view的嵌套层......我没有看到任何代码重复,你可以将MainCtrl放在一个单独的模块中,如果它困扰你那么多:

.config(['$routeProvider', function($routeProvider) {
  $routeProvider
  .when(..) 
  .otherwise({redirectTo: 'http://yourExternalSite.com/404.html'}); 
}])
.controller('MainCtrl',[ // <- Use this controller outside of the ng-view!
  '$rootScope','$window',
  function($rootScope,$window){
    $rootScope.$on("$routeChangeStart", function (event, next, current) {
      // next.$$route <-not set when routed through 'otherwise' since none $route were matched
      if (next && !next.$$route) {
        event.preventDefault(); // Stops the ngRoute to proceed with all the history state logic
        // We have to do it async so that the route callback 
        // can be cleanly completed first, so $timeout works too
        $rootScope.$evalAsync(function() {
          // next.redirectTo would equal be 'http://yourExternalSite.com/404.html'
          $window.location.href = next.redirectTo;
        });
      }
    });
  }
]);

干杯