为什么使用CryptoJS进行哈希计算会在Angular中导致$ rootScope:infdig错误? [英] Why would a hash computation using CryptoJS cause a $rootScope:infdig error in Angular?
问题描述
我有一个简单的页面,该页面显示有人在页面中键入字符串时的哈希值。我发现页面出现JavaScript错误
I have a simple page that shows the hash of a string as someone types it into the page. I found that the page had a JavaScript error
错误:[$ rootScope:infdig] http://errors.angularjs.org/1.2.26/ $ rootScope / infdig?p0 = 10& p1 =%5B%5B%22sha1…75651%2C1080464653%2C- 772792499%5D%2C%5C%22sigBytes%5C%22%3A20%7D%22%5D%5D
Error: [$rootScope:infdig] http://errors.angularjs.org/1.2.26/$rootScope/infdig?p0=10&p1=%5B%5B%22sha1…75651%2C1080464653%2C-772792499%5D%2C%5C%22sigBytes%5C%22%3A20%7D%22%5D%5D
页面的非常简化的版本是
A very simplified version of the page is
<html lang="en">
<head>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha1.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script>
function MyCtrl($scope) {
$scope.sha1 = function(pwd) {
return CryptoJS.SHA1(pwd);
};
}
</script>
</head>
<body>
<div class="app" ng-app ng-controller="MyCtrl">
<span ng-bind="sha1('bar')"></span>
</div>
</body>
</html>
可以作为Plunker http://plnkr.co/edit/vmBtH8B2EKsdcfZVGlMH 。
which is available as Plunker http://plnkr.co/edit/vmBtH8B2EKsdcfZVGlMH.
我在原始页面中尝试执行的操作已重新计算当有人在表单字段中键入哈希值时,输入字段定义如下所示:
What I am trying to do in the original page is recalculate the hash as someone types into the form field, and the input field definition looked like this
<input id="password" ng-model="password" type="text" placeholder="Password">
ng-bind实际上是 ng-bind = sha1(password )。
,但是在Plunker中,简单的静态情况表现出相同的行为。
and the ng-bind is really ng-bind="sha1(password)"
, but the simple static case in the Plunker exhibits the same behavior.
我了解到infdig错误与$ digest循环过多有关,但我看不出这将如何发生。似乎哈希计算会触发错误,因为从sha1函数返回静态字符串不会导致错误。
I gather that the infdig error has to do with too many $digest cycles, but I don't see how that would happen here. It looks like the hash computation triggers the error, because returning a static string from the sha1 function causes no error.
推荐答案
提供 ng-bind = sha1('bar')
使摘要循环不稳定,每次sha1函数返回不同的对象(引用不同)并且摘要循环必须再次运行为了使其稳定,每个摘要循环都会再次评估ng-bind函数表达式,并一直持续到达到最大限制集(10)。您也可以通过在作用域方法中执行 return []
来轻松复制此问题。这不是将函数表达式绑定到 ng-bind
的良好实践的副作用,因为它在每个摘要循环中运行,如果使用了它,则应仔细评估。
Providing ng-bind="sha1('bar')"
makes the digest cycle unstable, everytime sha1 function returns a different object (reference is different) and your digest cycle has to run again to stabilize it and every digest cycle again evaluates the ng-bind function expression and it goes on till it reaches the max limit set (10). You can also easily replicate this issue by just doing return []
in your scope method. This is just a side effect of not so good practice of binding a function expression to ng-bind
as it runs every digest cycle, if at all used it should be carefully evaluated.
一个简单的解决方案是将ng-change / ng-blur事件绑定到您的密码或任何其他触发器上,然后仅将ng-bind绑定到属性而不是函数表达式上。
One simple solution is to bind ng-change/ng-blur event on your password or any other trigger and just bind ng-bind to a property instead of a function expression.
angular.module('app',[])
.constant('Crypto', window.CryptoJS);
function MyCtrl($scope, Crypto) {
$scope.encrypt = function() {
$scope.encrypted = Crypto.SHA1($scope.password);
};
}
<html lang="en" ng-app="app">
<head>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha1.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
</head>
<body>
<div class="app" ng-app ng-controller="MyCtrl">
<input id="password" ng-model="password" type="password" placeholder="Password" ng-change="encrypt()">
<span ng-bind="encrypted"></span>
</div>
</body>
</html>
为了更好地使用DI,我将crpto放在一个常量中,并在需要的地方注入它。
For better usage of DI i have placed crpto in a constant and inject it where needed.
这篇关于为什么使用CryptoJS进行哈希计算会在Angular中导致$ rootScope:infdig错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!