如何在401状态代码响应中避免$ compile:tpload错误

sys*_*out 15 javascript angularjs single-page-application angularjs-routing

我们正在使用AngularJS和ASP.NET MVC Json Rest API开发单页应用程序.

当一个未认证的客户端试图导航到一个私人途径(例如:/美孚/主页/模板)得到一个模板,它就会从Web API 401响应和我们的AngularJS应用程序会自动将其重定向到登录页面.

我们使用$ http拦截器处理401,如下所示:

if (response.status === 401) { 
        $location.path(routeToLogin);
        return $q.reject(response);
}
Run Code Online (Sandbox Code Playgroud)

输入正确的凭据允许客户端获取模板.

除了一个细节,一切都很完美; Javascript控制台报告此错误:

Error: [$compile:tpload] http://errors.angularjs.org/1.3.0/$compile/tpload?p0=%Foo%2FHome%2FTemplate%2F
Run Code Online (Sandbox Code Playgroud)

AngularJs文档说明了这一点:

描述

当$ compile尝试从某个URL获取模板时,会发生此错误,并且请求失败.

在我们的AngularJs应用程序中,请求失败但是它是设计的,因为资源在那里但是无法访问(401).

我应该继续在控制台上接受这种错误,还是可以以某种方式静音或屏蔽它?

编辑:

我已经调试了一点角度源,我发现代码的哪一部分引发了异常.
由于我们使用TemplateUrl声明模板,我们间接使用compileTemplateUrl调用此函数的函数:

$templateRequest($sce.getTrustedResourceUrl(templateUrl))
Run Code Online (Sandbox Code Playgroud)

这留下了未定义的第二个参数(ignoreRequestError)templateRequest.

ignoreRequestError(可选)布尔

是否在请求失败或模板为空时忽略异常

当我们的http拦截器,处理401状态代码,拒绝承诺,内部的$ http.get $TemplateRequestProvider失败并调用此函数:

 function handleError() {
        self.totalPendingRequests--;
        if (!ignoreRequestError) {
          throw $compileMinErr('tpload', 'Failed to load template: {0}', tpl);
        }
        return $q.reject();
      }
Run Code Online (Sandbox Code Playgroud)

我相信我们无法阻止控制台上的错误,因为TemplateUrl不允许将ignoreRequestError标志设置为false.

在401状态代码的情况下,我试图绕过拒绝; 这修复了控制台上的错误,但遗憾的是它有副作用:一个空模板被错误地缓存到TemplateCache导致其他问题.

Pin*_*niH 14

经过一番思考,我记得在Angular中装饰,它完美地解决了这个问题:

app.config(['$provide', function($provide) {
  $provide.decorator('$templateRequest', ['$delegate', function($delegate) {

    var fn = $delegate;

    $delegate = function(tpl) {

      for (var key in fn) {
        $delegate[key] = fn[key];
      }

      return fn.apply(this, [tpl, true]);
    };

    return $delegate;
  }]);
}]);
Run Code Online (Sandbox Code Playgroud)