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 相关文章推荐
jquery下checked取值问题的解决方法
Aug 09 Javascript
图片Slider 带左右按钮的js示例
Aug 30 Javascript
javascript的渐进增强与平稳退化浅谈
Nov 12 Javascript
5个可以帮你理解JavaScript核心闭包和作用域的小例子
Oct 08 Javascript
JavaScript encodeURI 和encodeURIComponent
Dec 04 Javascript
JavaScript DOM 对象深入了解
Jul 20 Javascript
Angular4的输入属性与输出属性实例详解
Nov 29 Javascript
在vue项目中安装使用Mint-UI的方法
Dec 27 Javascript
Vue精简版风格概述
Jan 30 Javascript
如何以Angular的姿势打开Font-Awesome详解
Apr 22 Javascript
微信小程序聊天功能的示例代码
Jan 13 Javascript
JavaScript中this函数使用实例解析
Feb 21 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
php面向对象全攻略 (九)访问类型
2009/09/30 PHP
PHP ? EasyUI DataGrid 资料存的方式介绍
2012/11/07 PHP
php如何解决无法上传大于8M的文件问题
2014/03/10 PHP
php检查函数必传参数是否存在的实例详解
2017/08/28 PHP
Laravel 微信小程序后端实现用户登录的示例代码
2019/11/26 PHP
比较全的JS checkbox全选、取消全选、删除功能代码
2008/12/19 Javascript
Javascript中的for in循环和hasOwnProperty结合使用
2013/06/05 Javascript
js中top的作用深入剖析
2014/03/04 Javascript
JS实现横向与竖向两个选项卡Tab联动的方法
2015/09/27 Javascript
javascript动画之模拟拖拽效果篇
2016/09/26 Javascript
JS文件上传神器bootstrap fileinput详解
2021/01/28 Javascript
js实现表格筛选功能
2017/01/18 Javascript
整理关于Bootstrap排版的慕课笔记
2017/03/29 Javascript
JavaScript简单实现合并两个Json对象的方法示例
2017/10/16 Javascript
5分钟学会Vue动画效果(小结)
2018/07/21 Javascript
pm2发布node配置文件ecosystem.json详解
2019/05/15 Javascript
图解javascript作用域链
2019/05/27 Javascript
js的新生代垃圾回收知识点总结
2019/08/22 Javascript
layui 数据表格+分页+搜索+checkbox+缓存选中项数据的方法
2019/09/21 Javascript
vue全局使用axios的操作
2020/09/08 Javascript
[02:35]DOTA2英雄基础教程 狙击手
2014/01/14 DOTA
Python Sqlite3以字典形式返回查询结果的实现方法
2016/10/03 Python
利用python将图片转换成excel文档格式
2017/12/30 Python
Python获取昨天、今天、明天开始、结束时间戳的方法
2018/06/01 Python
关于python2 csv写入空白行的问题
2018/06/22 Python
python爬虫爬取笔趣网小说网站过程图解
2019/11/18 Python
解决django 向mysql中写入中文字符出错的问题
2020/05/18 Python
tensorflow dataset.shuffle、dataset.batch、dataset.repeat顺序区别详解
2020/06/03 Python
浅谈pytorch中torch.max和F.softmax函数的维度解释
2020/06/28 Python
Python实现冒泡排序算法的完整实例
2020/11/04 Python
HTML5移动端开发中的Viewport标签及相关CSS用法解析
2016/04/15 HTML / CSS
Structs界面控制层技术
2013/10/11 面试题
交通局领导班子群众路线教育实践活动对照检查材料思想汇报
2014/10/09 职场文书
2014年建筑工程工作总结
2014/12/03 职场文书
钱学森电影观后感
2015/06/04 职场文书
Python OpenCV 彩色与灰度图像的转换实现
2021/06/05 Python