$ http拦截器中的Angular UI Bootstrap模式对话框挂起浏览器

2oo*_*oom 3 angularjs angular-ui angularjs-directive angular-ui-bootstrap angularjs-http

我正在尝试实现延迟授权,只有当用户触发调用需要身份验证的API时才会引入登录对话框.我正在使用bootstrap ui.bootstrap.modal(以及模态中的ui.bootstrap.alert).问题是这些指令明确指定了以下内容teamplateUrl:

  • template/modal/backdrop.html(在modal.js 这里)
  • template/modal/window.html(在modal.js 这里)
  • template/alert/alert.html(在alert.js 这里)

像这样:

.directive('modalBackdrop', ['$timeout', function ($timeout) {
  return {
    restrict: 'EA',
    replace: true,
    templateUrl: 'template/modal/backdrop.html',
    link: function (scope, element, attrs) {
      /* ... */
    }
  };
}])
Run Code Online (Sandbox Code Playgroud)

每当我调用$modal.open()ui-bootstrap为新的模态窗口构建DOM时,angular会尝试通过$http服务解析这些URL,即使模板已经通过$templateCache.put方法或添加<script>标记加载.这基本上是在我的拦截器中引起无限递归,它试图在request上面的url的重载中引入登录对话框.

这是我的拦截器的简化版本:

.config(['$provide', '$httpProvider', function($provide, $httpProvider) {
    $provide.factory('testInterceptor', ['$injector', function($injector) {
        return {
        'request': function(config) {

            var auth = $injector.get('authService');
            var modal = $injector.get('$modal');
            if (!auth.LoggedIn) {
              var loginModal = modal.open({
                  template: 'Login screen <alert type="warning">some message</alert>',
              });
              return loginModal.result;
            }
            return config;
          }
}}]);
Run Code Online (Sandbox Code Playgroud)

工作演示就在这里

任何人都可以提出建议,这将不涉及使用templateUrls的硬编码的方法ui.bootstrap.modalui.bootstrap.alert

我也在 github上报告了这个问题.

sir*_*rhc 5

解决此问题的一种简单方法是不对对以任何开头的URL的请求强制执行身份验证template/.像这样:

      $provide.factory('testIntercepter', ['$q', '$injector',
        function($q, $injector) {
          return {
            'request': function(config) {
              if (config.url.indexOf('template/') == 0) {
                log('ignoring ' + config.url);
                return config;
              }

              log(config.method + ' ' + config.url);
              var auth = $injector.get('authService');
              if (!auth.LoggedIn) {
                return auth.Login();
              }
              return config;
            },
          }
        }
      ]);
Run Code Online (Sandbox Code Playgroud)

示例Plunker:http://plnkr.co/edit/kADmHkfHiyKW8kd7aNep?p = preview


更复杂的选项可能是检查$templateCache它是否包含所请求的URL,并跳过这些情况的身份验证:

      $provide.factory('testIntercepter', ['$q', '$injector', '$templateCache',
        function($q, $injector, $templateCache) {
          return {
            'request': function(config) {
              if ($templateCache.get(config.url)) {
                log('in $templateCache ' + config.url);
                return config;
              }

              log(config.method + ' ' + config.url);
              var auth = $injector.get('authService');
              if (!auth.LoggedIn) {
                return auth.Login();
              }
              return config;
            },
          }
        }
      ]);
Run Code Online (Sandbox Code Playgroud)

Plunker:http://plnkr.co/edit/RfkTmGinobxIWmg1BrMJ?p = preview