欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解AngularJs中$sce与$sceDelegate上下文转义服务

程序员文章站 2022-10-18 16:14:05
一、严格的上下文转义服务 严格的上下文转义(sce)是一种需要在一定的语境中导致angularjs绑定值被标记为安全使用语境的模式。由用户通过ng-bind-html绑定...

一、严格的上下文转义服务

严格的上下文转义(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”]);
 }]);

总结

以上就是这篇文章的全部内容,希望能对大家的学习或者工作带来一定的帮助,如果有疑问大家可以留言交流。