Ember - 获取转换的目标URL

3

我正在创建一个错误钩子(error hook)在我的Ember.js应用程序中。如果您无权查看某些内容(换句话说,如果服务器返回401),则会将您重定向到身份验证服务。

它看起来像这样:

Ember.Route = Ember.Route.extend({
  error: function(error, transition){
    if (error.status === 401) {
      window.location.replace("https://auth.censored.co.za");
    }
  }

我们的认证API如下工作:如果您发送了一个名为target的参数(它是一个URL),在您登录后,它将重定向回该目标URL。
因此,我想以某种方式获取Ember应用程序尝试转换到的路由的URL。
然后我的代码将变成这样。
Ember.Route = Ember.Route.extend({
  error: function(error, transition){
    if (error.status === 401) {
      var target = // Your answer here
      window.location.replace("https://auth.censored.co.za?target=" + encodeURIComponent(target));
    }
  }
4个回答

4
我也遇到了这个需求,我使用了一些内部API。在我的情况下,我想重新加载整个应用程序,以便如果您切换用户,则没有来自其他用户的数据。当我重新加载应用程序时,我希望将用户放置在他们试图转换到但权限不足的URL上。在他们进行身份验证后(因此在localstorage中有承载令牌),我想使用window.location.replace(url)获取整个应用程序的干净副本,并将用户放置在由Ember Transition对象暗示的URL上。但问题是,如何从Transition对象转换为URL?以下是我的解决方案,它使用路由器的私有API generate方法:
  let paramsCount = 0;
  let params = {};
  let args = [transition.targetName];
  // Iterate over route segments
  for (let key1 in transition.params) {
    if (transition.params.hasOwnProperty(key1)) {
      let segment = transition.params[key1];
      // Iterate over the params for the route segment.
      for (let key2 in segment) {
        if (segment.hasOwnProperty(key2)) {
          if (segment[key2] != null) {
            params[key2] = segment[key2];
            paramsCount++;
          }
        }
      }
    }
  }
  if (paramsCount > 0) {
    args.push(params);
  }
  let url = router.generate.apply(router, args);

你需要以某种方式获取路由器,可以通过容器查找或其他方式。我是通过注入已记录为API的-routing服务(可能在未来公开使用,被link-to使用),并且它恰好具有路由器作为属性来获得它。
虽然比较杂乱,但也许你会发现这有帮助。

2

1

Kevins的回答是最正确的,我得出了类似的解决方案。基本上,我找到了link-to组件如何填充href属性的代码,并使用了同样类型的代码。

在你的对象中注入-routing。我是这样做的:

'routing': Ember.inject.service('-routing'),

然后,从转换生成URL的代码如下...

let routing = this.get('routing');
let params = Object.values(transition.params).filter(param => {
  return Object.values(param).length;
});
let url = routing.generateURL(transition.targetName, params, transition.queryParams);

1
经过几个小时的搜索和使用Chrome调试器尝试反向工程Ember 2.5代码后,我的结论是目前你所寻找的是不可能实现的。对于那些不理解为什么有人想要这样做的人来说,当身份验证(例如登录页面)与应用程序分离时,就会出现这种情况。如果有要求在用户未经过身份验证时不提供任何内容(包括应用程序本身),则必须这样做。换句话说,在登录之前,用户无权访问应用程序,因此登录页面不能成为应用程序的一部分。PS:我意识到这不是用户问题的解决方案,可能更适合作为评论。但是,我无法发布评论。

“无解”也是一个合法的答案 - 感谢您的反馈。 - Marco Prins

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接