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)