详解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 相关文章推荐
JavaScript面向对象程序设计三 原型模式(上)
Dec 21 Javascript
Jquery图形报表插件 jqplot简介及参数详解
Oct 10 Javascript
jquery实现简单的自动播放幻灯片效果
Jun 13 Javascript
利用JS轻松实现获取表单数据
Dec 06 Javascript
在javascript中,null>=0 为真,null==0却为假,null的值详解
Feb 22 Javascript
vue2.0实现导航菜单切换效果
May 08 Javascript
详解vue服务端渲染(SSR)初探
Jun 19 Javascript
浅谈gulp创建完整的项目流程
Dec 20 Javascript
vue实现裁切图片同时实现放大、缩小、旋转功能
Mar 02 Javascript
在react-router4中进行代码拆分的方法(基于webpack)
Mar 08 Javascript
为什么说JavaScript预解释是一种毫无节操的机制详析
Nov 18 Javascript
JS实现图片轮播效果实例详解【可自动和手动】
Apr 04 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
MySQL时间字段究竟使用INT还是DateTime的说明
2012/02/27 PHP
PHP json_encode中文乱码问题的解决办法
2013/09/09 PHP
php如何连接sql server
2015/10/16 PHP
PHP制作用户注册系统
2015/10/23 PHP
获取当前网页document.url location.href区别总结
2008/05/10 Javascript
用js实现层随着内容大小动态渐变改变 推荐
2009/12/19 Javascript
用js实现判断当前网址的来路如果不是指定的来路就跳转到指定页面
2011/05/02 Javascript
jquery在项目中做复选框时遇到的一些问题笔记
2013/11/17 Javascript
Jquery异步提交表单代码分享
2015/03/26 Javascript
原生JavaScript实现滚动条效果
2020/03/24 Javascript
基于Particles.js制作超炫粒子动态背景效果(仿知乎)
2017/09/13 Javascript
Vue 动态组件与 v-once 指令的实现
2019/02/12 Javascript
超简单的微信小程序轮播图
2019/11/22 Javascript
简单了解JavaScript弹窗实现代码
2020/05/07 Javascript
jquery更改元素属性attr()方法操作示例
2020/05/22 jQuery
Js on及addEventListener原理用法区别解析
2020/07/11 Javascript
Element-ui树形控件el-tree自定义增删改和局部刷新及懒加载操作
2020/08/31 Javascript
在vue中使用inheritAttrs实现组件的扩展性介绍
2020/12/07 Vue.js
[05:40]DOTA2荣耀之路6:Wings最后进攻
2018/05/30 DOTA
Python中使用Tkinter模块创建GUI程序实例
2015/01/14 Python
使用Python的Scrapy框架编写web爬虫的简单示例
2015/04/17 Python
学习python之编写简单乘法口诀表实现代码
2016/02/27 Python
使用pygame模块编写贪吃蛇的实例讲解
2018/02/05 Python
对pandas中apply函数的用法详解
2018/04/10 Python
python编写简易聊天室实现局域网内聊天功能
2018/07/28 Python
pytorch 图像预处理之减去均值,除以方差的实例
2020/01/02 Python
python实现批量转换图片为黑白
2020/06/16 Python
英国露营设备和户外服装购物网站:Simply Hike
2019/05/05 全球购物
酒店执行总经理岗位职责
2013/12/15 职场文书
市场策划求职信
2014/08/07 职场文书
工作保证书怎么写
2015/02/28 职场文书
农村婚庆主持词
2015/06/29 职场文书
教育读书笔记
2015/07/02 职场文书
关于食品安全的演讲稿范文(三篇)
2019/10/21 职场文书
Python的这些库,你知道多少?
2021/06/09 Python
MySQL 5.7常见数据类型
2021/07/15 MySQL