我正在构建一个说明常见应用漏洞(如sql注入)的站点.我使用AngularJS和highlight.js来创建交互式的例子.
如何使AngularJS和highlight.js更新我的代码片段?
例
This Fiddle演示如果用户的输入未被验证或消毒,在电子邮件字段中如何输入“OR 1 = 1”可能会更改查询的预期行为.
SELECT * FROM dbo.Users WHERE Email='{{email}}' AND Password='{{password}}'
当用户输入电子邮件地址和密码时,Angular会更新查询.但是,语法突出显示不会更新.
SELECT * FROM dbo.Users WHERE Email='user@domain.com' AND Password=''
我尝试重新初始化hljs,但是当我做角停止更新查询.
hljs.initHighlighting.called = false; hljs.initHighlighting();
应用
<script>
var app = angular.module("app",['hljs']);
app.controller("controller",function($scope) {
$scope.email = "user@domain.com";
$scope.password = "";
})
</script>
<div ng-app="app" ng-controller="controller">
<div>
<div class="row">
<div class="col-sm-4">Email
<input type="text" class="form-control" ng-model="email">
</div>
<div class="col-sm-4">Password
<input type="text" class="form-control" ng-model="password">
</div>
</div>
<br>
<div hljs include="'compile-me'" compile="true" language="sql"></div>
</div>
<script type="text/ng-template" id="compile-me">
SELECT * FROM dbo.Users WHERE Email = '{{email}}'
AND Password = '{{password}}'
</script>
</div>
解决方法
在jsfiddle你提供你使用
angular-highlightjs这在你的情况基本上:
>获取您提供的模板,include指令适用
>在生成HTML标记的模板上调用highlightjs库API,其中突出显示的元素具有特定语言的正确样式
>然后将突出显示的HTML标记传递给angularjs $compile
之后不会发生高光,尤其是当内插的内容发生变化时.
解决它的一个方法是使用来自angular-highlightjs的源指令,这是被观察到的,但我认为构建自定义指令更简单.
这里的诀窍是手动内插和突出显示内容.我已经更新了您的fiddle与一个简单的高亮指令,提出了想法:
app.directive('highlight',function($interpolate,$window){
return {
restrict: 'EA',scope: true,compile: function (tElem,tAttrs) {
var interpolateFn = $interpolate(tElem.html(),true);
tElem.html(''); // stop automatic intepolation
return function(scope,elem,attrs){
scope.$watch(interpolateFn,function (value) {
elem.html(hljs.highlight('sql',value).value);
});
}
}
};
});