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


Posted in Javascript onSeptember 21, 2016

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

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

总结

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

Javascript 相关文章推荐
出现“不能执行已释放的Script代码”错误的原因及解决办法
Aug 29 Javascript
用js实现层随着内容大小动态渐变改变 推荐
Dec 19 Javascript
JQuery动态创建DOM、表单元素的实现代码
Aug 09 Javascript
javascript动画浅析
Aug 30 Javascript
js实现拖拽 闭包函数详细介绍
Nov 25 Javascript
JQuery插件Quicksand实现超炫的动画洗牌效果
May 03 Javascript
点击页面任何位置隐藏div的实现方法
Sep 05 Javascript
Vue组件通信之Bus的具体使用
Dec 28 Javascript
微信小程序map组件结合高德地图API实现wx.chooseLocation功能示例
Jan 23 Javascript
如何阻止小程序遮罩层下方图层滚动
Sep 05 Javascript
js实现滚动条自动滚动
Dec 13 Javascript
javascript函数式编程基础
Sep 15 Javascript
JS 获取HTML标签内的子节点的方法
Sep 21 #Javascript
浅谈JS使用[ ]来访问对象属性
Sep 21 #Javascript
js style.display=block显示布局错乱问题的解决方法
Sep 21 #Javascript
JS封装的选项卡TAB切换效果示例
Sep 20 #Javascript
jquery radio的取值_radio的选中_radio的重置方法
Sep 20 #Javascript
JS获取鼠标相对位置的方法
Sep 20 #Javascript
jQuery flip插件实现的翻牌效果示例【附demo源码下载】
Sep 20 #Javascript
You might like
php二维数组合并及去重复的方法
2015/03/04 PHP
laravel 之 Eloquent 模型修改器和序列化示例
2019/10/17 PHP
单击按钮显示隐藏子菜单经典案例
2013/01/04 Javascript
登陆成功后自动计算秒数执行跳转
2014/01/23 Javascript
javascript中的遍历for in 以及with的用法
2014/12/22 Javascript
14个有用的Jquery技巧分享
2015/01/08 Javascript
jQuery实现的给图片点赞+1动画效果(附在线演示及demo源码下载)
2015/12/31 Javascript
详解Javascript继承的实现
2016/03/25 Javascript
必备的JS调试技巧汇总
2016/07/20 Javascript
js记录点击某个按钮的次数-刷新次数为初始状态的实例
2017/02/15 Javascript
微信小程序 在线支付功能的实现
2017/03/14 Javascript
Angular2安装angular-cli
2017/05/21 Javascript
BootStrap daterangepicker 双日历控件
2017/06/02 Javascript
ionic环境配置及问题详解
2017/06/27 Javascript
vue-router 起步步骤详解
2019/03/26 Javascript
深入浅析ng-bootstrap 组件集中 tabset 组件的实现分析
2019/07/19 Javascript
vue filter 完美时间日期格式的代码
2019/08/14 Javascript
Python中列表(list)操作方法汇总
2014/08/18 Python
Python使用Flask框架获取当前查询参数的方法
2015/03/21 Python
Python实现选择排序
2017/06/04 Python
python绘图模块matplotlib示例详解
2019/07/26 Python
python turtle工具绘制四叶草的实例分享
2020/02/14 Python
PyTorch中Tensor的数据统计示例
2020/02/17 Python
python drf各类组件的用法和作用
2021/01/12 Python
各大浏览器 CSS3 和 HTML5 兼容速查表 图文
2010/04/01 HTML / CSS
意大利奢侈品购物网站:Deliberti
2019/10/08 全球购物
HomeAway英国:全球领先的度假租赁在线市场
2020/02/03 全球购物
初级软件工程师面试题 Junior Software Engineer Interview
2015/02/15 面试题
电大本科自我鉴定
2014/02/05 职场文书
《童年》教学反思
2014/02/18 职场文书
培训研修方案
2014/06/06 职场文书
2014年体育部工作总结
2014/11/13 职场文书
2014年业务工作总结
2014/11/17 职场文书
小学体育组工作总结
2015/08/13 职场文书
使用HttpSessionListener监听器实战
2022/03/17 Java/Android
蓝牙耳机怎么连接电脑win11? Win11蓝牙耳机连接电脑的技巧
2023/01/09 数码科技