AngularJS 使用$sce控制代码安全检查


Posted in Javascript onJanuary 05, 2016

由于浏览器都有同源加载策略,不能加载不同域下的文件、也不能使用不合要求的协议比如file进行访问。

在angularJs中为了避免安全漏洞,一些ng-src或者ng-include都会进行安全校验,因此常常会遇到 一个iframe中的ng-src无法使用。

什么是SCE

SCE,即strict contextual escaping,我的理解是 严格的上下文隔离  ...翻译的可能不准确,但是通过字面理解,应该是angularjs严格的控制上下文访问。

由于angular默认是开启SCE的,因此也就是说默认会决绝一些不安全的行为,比如你使用了某个第三方的脚本或者库、加载了一段html等等。

这样做确实是安全了,避免一些跨站XSS,但是有时候我们自己想要加载特定的文件,这时候怎么办呢?

此时可以通过$sce服务把一些地址变成安全的、授权的链接...简单地说, 就像告诉门卫,这个陌生人其实是我的好朋友,很值得信赖,不必拦截它!

常用的方法有:

$sce.trustAs(type,name);
$sce.trustAsHtml(value);
$sce.trustAsUrl(value);
$sce.trustAsResourceUrl(value);
$sce.trustAsJs(value);

其中后面的几个都是基于第一个api使用的,比如trsutAsUrl其实调用的是trsutAs($sce.URL,"xxxx");

其中 type 可选的值为:

$sce.HTML
$sce.CSS
$sce.URL //a标签中的href , img标签中的src
$sce.RESOURCE_URL //ng-include,src或者ngSrc,比如iframe或者Object
$sce.JS

来自官网的例子:ng-bind-html

<!DOCTYPE html>
<html>
<head>
  <title></title>
  <script src="http://apps.bdimg.com/libs/angular.js/1.2.16/angular.min.js"></script>
</head>
<body ng-app="mySceApp">
  <div ng-controller="AppController">
   <i ng-bind-html="explicitlyTrustedHtml" id="explicitlyTrustedHtml"></i>
  </div>
  <script type="text/javascript">
    angular.module('mySceApp',[])
    .controller('AppController', ['$scope', '$sce',
     function($scope, $sce) {
      $scope.explicitlyTrustedHtml = $sce.trustAsHtml(
        '<span onmouseover="this.textContent="Explicitly trusted HTML bypasses ' +
        'sanitization."">Hover over this text.</span>');
     }]);
  </script>
</body>
</html>

实际工作中的例子:ng-src链接

<!DOCTYPE html>
<html>
<head>
  <title></title>
  <script src="http://apps.bdimg.com/libs/angular.js/1.2.16/angular.min.js"></script>
</head>
<body ng-app="mySceApp">
<div ng-controller="AppController">
  <iframe width="100%" height="100%" seamless frameborder="0" ng-src="{{trustSrc}}"></iframe>
</div>
  <script type="text/javascript">
    angular.module('mySceApp',[])
    .controller('AppController', ['$scope','$sce',function($scope,$sce) {
      $scope.trustSrc = $sce.trustAs($sce.RESOURCE_URL,"http://fanyi.youdao.com/");
      // $scope.trustSrc = $sce.trustAsResourceUrl("http://fanyi.youdao.com/");//等同于这个方法
     }]);
  </script>
</body>
</html>

还有点时间,接着给大家介绍angular中的ng-bind-html指令和$sce服务

angular js的强大之处之一就是他的数据双向绑定这一牛B功能,我们会常常用到的两个东西就是ng-bind和针对form的ng-model。但在我们的项目当中会遇到这样的情况,后台返回的数据中带有各种各样的html标签。如:

$scope.currentWork.description = “hello,<br><b>今天我们去哪里?</b>”
我们用ng-bind-html这样的指令来绑定,结果却不是我们想要的。是这样的

hello,

今天我们去哪里?

怎么办呢?

对于angular 1.2一下的版本我们必须要使用$sce这个服务来解决我们的问题。所谓sce即“Strict Contextual Escaping”的缩写。翻译成中文就是“严格的上下文模式”也可以理解为安全绑定吧。来看看怎么用吧。

controller code:

$http.get('/api/work/get?workId=' + $routeParams.workId).success(function (work) {$scope.currentWork = work;});

HTML code:

<p> {{currentWork.description}}</p>

我们返回的内容中包含一系列的html标记。表现出来的结果就如我们文章开头所说的那样。这时候我们必须告诉它安全绑定。它可以通过使用$ sce.trustAsHtml()。该方法将值转换为特权所接受并能安全地使用“ng-bind-html”。所以,我们必须在我们的控制器中引入$sce服务

controller('transferWorkStep2', ['$scope','$http','$routeParams','$sce', function ($scope,$http, $routeParams, $sce) {
$http.get('/api/work/get?workId=' + $routeParams.workId)
.success(function (work) {
  $scope.currentWork = work;
  $scope.currentWork.description = $sce.trustAsHtml($rootScope.currentWork.description);
});

html code:

<p ng-bind-html="currentWork.description"></p>

这样结果就完美的呈现在页面上了:

hello

今天我们去哪里?

咱们还可以这样用,把它封装成一个过滤器就可以在模板上随时调用了

app.filter('to_trusted', ['$sce', function ($sce) {
return function (text) {
  return $sce.trustAsHtml(text);
};
}]);

html code:

全选复制放进笔记

<p ng-bind-html="currentWork.description | to_trusted"></p>
Javascript 相关文章推荐
JavaScript 继承详解(三)
Jul 13 Javascript
jQuery AJAX 调用WebService实现代码
Mar 24 Javascript
jQuery EasyUI API 中文文档 - Spinner微调器使用
Oct 21 Javascript
关于Javascript与iframe的那些事儿
Jul 04 Javascript
javascript的parseFloat()方法精度问题探讨
Nov 26 Javascript
搭建pomelo 开发环境
Jun 24 Javascript
jQuery中extend函数详解
Feb 13 Javascript
node.js+express制作网页计算器
Jan 17 Javascript
浅谈js图片前端预览之filereader和window.URL.createObjectURL
Jun 30 Javascript
vue.js input框之间赋值方法
Aug 24 Javascript
ajaxfileupload.js实现上传文件功能
Apr 19 Javascript
vue使用axios实现excel文件下载的功能
Jul 16 Javascript
JS常见问题之为什么点击弹出的i总是最后一个
Jan 05 #Javascript
浅谈javascript 函数表达式和函数声明的区别
Jan 05 #Javascript
JavaScript实现下拉菜单的显示和隐藏
Jan 05 #Javascript
jQuery实现二级下拉菜单效果
Jan 05 #Javascript
基于JavaScript实现简单的随机抽奖小程序
Jan 05 #Javascript
jquery中ajax处理跨域的三大方式
Jan 05 #Javascript
基于JavaScript代码实现随机漂浮图片广告
Jan 05 #Javascript
You might like
MySQL授权问题总结
2007/05/06 PHP
php学习笔记 php中面向对象三大特性之一[封装性]的应用
2011/06/13 PHP
探讨捕获php错误信息方法的详解
2013/06/09 PHP
php强制文件下载而非在浏览器打开的自定义函数分享
2014/05/08 PHP
php动态添加url查询参数的方法
2015/04/14 PHP
Symfony2开发之控制器用法实例分析
2016/02/05 PHP
jquery 简单导航实现代码
2009/09/11 Javascript
Moment.js 不容错过的超棒Javascript日期处理类库
2012/04/15 Javascript
innerHTML,outerHTML,innerText,outerText的用法及区别解析
2013/12/16 Javascript
jQuery插件FusionCharts绘制的2D帕累托图效果示例【附demo源码】
2017/03/28 jQuery
node.js + socket.io 实现点对点随机匹配聊天
2017/06/30 Javascript
原生js封装添加class,删除class的实例
2017/11/06 Javascript
webpack 处理CSS资源的实现
2019/09/27 Javascript
[02:43]2018DOTA2亚洲邀请赛主赛事首日TOP5
2018/04/04 DOTA
[53:43]VP vs NewBee Supermajor 胜者组 BO3 第三场 6.5
2018/06/06 DOTA
[03:42]2018完美盛典-《加冕》
2018/12/16 DOTA
解决谷歌搜索技术文章时打不开网页问题的python脚本
2013/02/10 Python
python 写的一个爬虫程序源码
2016/02/28 Python
详解Python如何获取列表(List)的中位数
2016/08/12 Python
名片管理系统python版
2018/01/11 Python
python 读取鼠标点击坐标的实例
2018/12/29 Python
Django用户认证系统 Web请求中的认证解析
2019/08/02 Python
简单了解python 生成器 列表推导式 生成器表达式
2019/08/22 Python
python实现的分析并统计nginx日志数据功能示例
2019/12/21 Python
Python实例教程之检索输出月份日历表
2020/12/16 Python
英国鲜花速递:Serenata Flowers
2018/04/03 全球购物
美国牛仔品牌:True Religion
2018/11/16 全球购物
介绍一下Cookie和Session及他们之间的区别
2012/11/20 面试题
八年级物理教学反思
2014/01/19 职场文书
接受捐赠答谢词
2014/01/27 职场文书
5s推行计划书
2014/05/06 职场文书
C++程序员求职信
2014/05/07 职场文书
汽车广告策划方案
2014/05/31 职场文书
党员个人公开承诺书
2014/08/29 职场文书
Python+SeaTable实现计算两个日期间的工作日天数
2022/07/07 Python
OpenFeign实现远程调用
2022/08/14 Java/Android