详解AngularJs中$sce与$sceDelegate上下文转义服务
一、严格的上下文转义服务
严格的上下文转义(sce)是一种需要在一定的语境中导致angularjs绑定值被标记为安全使用语境的模式。由用户通过ng-bind-html
绑定任意html语句就是这方面的一个例子。我们称这些上下文转义为特权或者sce。
二、$sce
$sce 服务是angularjs提供的一种严格上下文转义服务。
下面代码是简化了的ngbindhtml实现(当然,这不是完整版ngbindhtml源码):
var ngbindhtmldirective = ['$sce', function($sce) { return function(scope, element, attr) { scope.$watch($sce.parseashtml(attr.ngbindhtml), function(value) { element.html(value || ''); }); }; }];
支持哪些信任的上下文类型?
$sce.html
将html代码安全的绑定到应用程序中。
$sce.css
将css样式代码安全的绑定到应用程序中。
$sce.url
将url安全的绑定到应用程序中并保证其可用。比如(href,src)
$sce.resource_url
将resource_url安全的绑定到应用程序中并保证其可用。比如(ng-href,ng-src)
$sce.js
将javascript代码安全的绑定到应用程序中。
如何使$sce服务可用或者不可用?
angular.module(“myapp”,[]).config([“$sceprovider”,function($sceprovider){ $sceprovider.enabled(true/false); }]);
使用:$sce();
方法:
isenabled();
返回一个boolean,指示是否可启用sce。
parseas(type,expression);
将angular表达式转换为一个函数。这类似$parse解析并且当表达式是常量时是相同的。否则,它将调用$sce.gettrusted(type,result)
将表达式包装。
type:在sce的上下文的使用的结果的类型。
expression:被编译的字符串表达式。
trustas(type,value);
代表$scedelegate.trustas。
type:上下文中能安全的被使用的值,如url,resourceurl,html,js和css。
value:需要被认为是安全或者值的信赖的值。
trustashtml(value);
$scedelegate.trustas($sce.html,value)的快捷方式。
value:被信任的值。
trustasurl(value);
$scedelegate.trustas($sce.url,value)的快捷方式。
value:被信任的值。
trustasresourceurl(value);
$scedelegate.trustas($sce.resource_url,value)的快捷方式。
value:被信任的值。
trustasjs(value);
$scedelegate.trustas($sce.js,value)的快捷方式。
value:被信任的值。
gettrusted(type,maybetrusted);
代表$scedelegate.gettrusted。因此,得到了$sce的结果。如果查询的上下文类型是一个创造型的类型,则调用trustas()并且返回原来提供的值。如果这个条件不满足,则抛出一个异常。
gettrustedhtml(value);
$scedelegate.gettrusted ($sce.html,value)的快捷方式。
value:通过$sce.gettrusted执行后的值。
gettrustedcss(value);
$scedelegate.gettrusted ($sce.css,value)的快捷方式。
value:通过$sce.gettrusted执行后的值。
gettrustedurl(value);
$scedelegate.gettrusted ($sce.url,value)的快捷方式。
value:通过$sce.gettrusted执行后的值。
gettrustedresourceurl(value);
$scedelegate.gettrusted ($sce.resource_url,value)的快捷方式。
value:通过$sce.gettrusted执行后的值。
gettrustedjs(value);
$scedelegate.gettrusted ($sce.js,value)的快捷方式。
value:通过$sce.gettrusted执行后的值。
parseashtml(expression);
$sce.parseas ($sce.html,value)的快捷方式。
value:被编译的字符串表达式。
parseascss(expression);
$sce.parseas ($sce.css,value)的快捷方式。
value:被编译的字符串表达式。
parseasurl(expression);
$sce.parseas ($sce.url,value)的快捷方式。
value:被编译的字符串表达式。
parseasresourceurl(expression);
$sce.parseas ($sce.resource_url,value)的快捷方式。
value:被编译的字符串表达式。
parseasjs(expression);
$sce.parseas ($sce.js,value)的快捷方式。
value:被编译的字符串表达式。
使用方式:
<div ng-app="demo" ng-controller="testctrl as ctrl"> <textarea ng-model="ctrl.jscontext"></textarea> <pre ng-bind="ctrl.jsbody"></pre> <button ng-click="ctrl.runjs()">run</button> <div ng-bind-html="ctrl.htmltext" class="mycss"></div> </div>
(function () { angular.module('demo', []) .controller('testctrl', ["$sce","$scope",testctrl]); function testctrl($sce,$scope) { var vm = this; $scope.$watch("ctrl.jscontext",function(n){ vm.jsbody = n; }); this.runjs = function() { eval(vm.jsbody.tostring()); }; vm.htmltext = "<h2>hello world</h2>"; vm.htmltext =$sce.trustashtml(this.htmltext); } }());
放在filter使用:
<div ng-app="demo" ng-controller="testctrl as ctrl"> <div ng-bind-html="ctrl.htmltext | trust:'html'"></div> </div>
(function () { angular.module('demo', []) .filter("trust",["$sce",trust]) .controller('testctrl', testctrl); function trust($sce){ return function(value,type){ return $sce.trustas(type,value); } }; function testctrl() { this.htmltext = "<h2>hello world</h2>"; } }());
上面是一个将不被angular认定为信任的html代码字符串通过$sce设置为信任的html代码并且插入的例子,这里用了个小技巧,也就没在controller进行这步操作了,直接放到一个filter服务内,只要在需要的地方过滤下即可,并且可指定类型,这里写成统一动态选择类型了。那么在啥时候需要用到这两个服务呢?在当使用ng-bind-html绑定html时报错:error: [$sce:unsafe]attempting to use an unsafe value in a safe context. 的时候使用。
三、$scedelegate
$scedelegate是一个angularjs为$sce服务提供严格的上下文转义服务的服务。
通常,你会配置或者重写$scedelegate去代替$sce服务以定制angularjs中的严格的上下文转义机制。当$sce提供众多的快捷方式,你其实只需要重写三个核心功能(trustas,gettrusted和valueof)来替代事件的工作方式,因为$sce代表了$scedelegate的这些操作。
当你完成了重写或配置$scedelegate用来改变$sce的行为时,一般情况下,需要配置$scedelegateprovider以代替你用于装载可信任的angularjs资源(如template)的白名单和黑名单。
使用:$scedelegate();
方法:
trustas(type,value);
返回一个在angular中作为指定的使用严格的上下文转义服务上下文中的值的对象使用。
type:上下文中能安全的被使用的值,如url,resourceurl,html,js和css。
value:需要被认为是安全或者值的信赖的值。
valueof(value);
如果传递的参数被上一个$scedelegate.trustas
调用返回,返回已通过$scedelegate.trustas
的值。否则返回原先的值。
value:上一个$scedelegate.trustas
调用的结果或者其他任何结果。
gettrusted(type,maybetrusted);
如果查询的上下文类型是一个创造型的类型,得到$scedelegate调用的结果并返回最初提供的值。如果这个条件不满意,抛出一个异常。
type:需要用到的值的类型。
value:上一个$scedelegate.trustas
调用的结果或者其他任何结果。
使用代码(配置白名单/黑名单):
angular.module('myapp', []).config([“$ scedelegateprovider”,function($scedelegateprovider) { $scedelegateprovider.resourceurlwhitelist([“whitelist value”]); $scedelegateprovider.resourceurlblacklist([“blacklist value”]); }]);
总结
以上就是这篇文章的全部内容,希望能对大家的学习或者工作带来一定的帮助,如果有疑问大家可以留言交流。