详解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 相关文章推荐
JS重要知识点小结
Nov 06 Javascript
利用js实现遮罩以及弹出可移动登录窗口
Jul 08 Javascript
Jquery利用mouseenter和mouseleave实现鼠标经过弹出层且可以点击
Feb 12 Javascript
setInterval计时器不准的问题解决方法
May 08 Javascript
js获取本机操作系统类型的两种方法
Dec 19 Javascript
AngularJS实现数据列表的增加、删除和上移下移等功能实例
Sep 05 Javascript
利用webstrom调试Vue.js单页面程序的方法教程
Jun 06 Javascript
javascript高级模块化require.js的具体使用方法
Oct 31 Javascript
webpack配置导致字体图标无法显示的解决方法
Mar 06 Javascript
Vue-router 切换组件页面时进入进出动画方法
Sep 01 Javascript
使用vue-cli脚手架工具搭建vue-webpack项目
Jan 14 Javascript
jquery实现图片放大镜效果
Dec 23 jQuery
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面向对象之多态
2014/08/20 PHP
Ubuntu 16.04下安装PHP 7过程详解
2017/03/28 PHP
php如何获取Http请求
2020/04/30 PHP
javascript Demo模态窗口
2009/12/06 Javascript
js图片延迟加载的实现方法及思路
2013/07/22 Javascript
jQuery怎么解析Json字符串(Json格式/Json对象)
2013/08/09 Javascript
js传参数受特殊字符影响错误的解决方法
2013/10/21 Javascript
javascript中定义类的方法汇总
2014/12/28 Javascript
纯JavaScript实现获取onclick、onchange等事件的值
2014/12/29 Javascript
什么是JavaScript注入攻击?
2016/09/14 Javascript
bootstrap制作jsp页面(根据值让table显示选中)
2017/01/05 Javascript
详解nodejs实现本地上传图片并预览功能(express4.0+)
2017/06/28 NodeJs
微信小程序点击控件修改样式实例详解
2017/07/07 Javascript
详解ES6之async+await 同步/异步方案
2017/09/19 Javascript
NW.js 简介与使用方法
2018/02/01 Javascript
详解vue-router 初始化时做了什么
2018/06/11 Javascript
vue实现div拖拽互换位置
2020/07/29 Javascript
JS实现获取当前所在周的周六、周日示例分析
2019/05/11 Javascript
JavaScript学习教程之cookie与webstorage
2019/06/23 Javascript
vue中实现点击按钮滚动到页面对应位置的方法(使用c3平滑属性实现)
2019/12/29 Javascript
js动态生成表格(节点操作)
2021/01/12 Javascript
[01:43]3.19DOTA2发布会 三代刀塔人第三代
2014/03/25 DOTA
讲解python参数和作用域的使用
2013/11/01 Python
浅谈Python中copy()方法的使用
2015/05/21 Python
Python实现按逗号分隔列表的方法
2018/10/23 Python
Django框架模板用法入门教程
2019/11/04 Python
Python利用Faiss库实现ANN近邻搜索的方法详解
2020/08/03 Python
使用CSS禁止textarea调整大小功能的方法
2015/03/13 HTML / CSS
Java面试题:说出如下代码的执行结果
2015/10/30 面试题
小学教师的个人自我鉴定
2013/10/24 职场文书
生产车间班组长岗位职责
2014/01/06 职场文书
小学生安全保证书
2015/05/09 职场文书
学困生帮扶工作总结
2015/08/13 职场文书
2015年挂职锻炼个人总结
2015/10/22 职场文书
jupyter notebook保存文件默认路径更改方法汇总(亲测可以)
2021/06/09 Python
MySQL实例精讲单行函数以及字符数学日期流程控制
2021/10/15 MySQL