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.ajax 用户登录验证代码
Oct 29 Javascript
基于jQuery的试卷自动排版系统实现代码
Jan 06 Javascript
JS 精确统计网站访问量的实例代码
Jul 05 Javascript
js实现iPhone界面风格的单选框和复选框按钮实例
Aug 18 Javascript
分享javascript计算时间差的示例代码
Mar 19 Javascript
BootstrapValidator超详细教程(推荐)
Dec 07 Javascript
解决JS外部文件中文注释出现乱码问题
Jul 09 Javascript
JavaScript常用事件介绍
Jan 21 Javascript
layui 表格操作列按钮动态显示的实现方法
Sep 06 Javascript
layui下拉框获取下拉值(select)的例子
Sep 10 Javascript
基于JavaScript实现控制下拉列表
May 08 Javascript
JavaScript实现简单日历效果
Sep 11 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编写的抽奖程序中奖概率算法
2015/05/14 PHP
ThinkPHP框架下微信支付功能总结踩坑笔记
2019/04/10 PHP
php面向对象程序设计入门教程
2019/06/22 PHP
Laravel 5.4前后台分离,通过不同的二级域名访问方法
2019/10/13 PHP
JavaScript 更严格的相等 [译]
2012/09/20 Javascript
JS在textarea光标处插入文本的小例子
2013/03/22 Javascript
教你如何自定义百度分享插件以及bshare分享插件的分享按钮
2014/06/20 Javascript
jquery中post方法用法实例
2014/10/21 Javascript
jQuery+HTML5美女瀑布流布局实现方法
2015/09/21 Javascript
js和jq使用submit方法无法提交表单的快速解决方法
2016/05/17 Javascript
浅谈Node.js:Buffer模块
2016/12/05 Javascript
原生JS轮播图插件
2017/02/09 Javascript
JS实现隔行换色的表格排序
2017/03/27 Javascript
手淘flexible.js框架使用和源代码讲解小结
2018/10/15 Javascript
vue生命周期与钩子函数简单示例
2019/03/13 Javascript
jQuery实现增删改查
2020/12/22 jQuery
[47:53]DOTA2上海特级锦标赛主赛事日 - 1 败者组第一轮#2COL VS Spirit
2016/03/02 DOTA
跟老齐学Python之集合的关系
2014/09/24 Python
PyCharm安装第三方库如Requests的图文教程
2018/05/18 Python
详解python的sorted函数对字典按key排序和按value排序
2018/08/10 Python
python selenium实现发送带附件的邮件代码实例
2019/12/10 Python
详解Python 重学requests发起请求的基本方式
2020/02/07 Python
利用4行Python代码监测每一行程序的运行时间和空间消耗
2020/04/22 Python
Python3实现个位数字和十位数字对调, 其乘积不变
2020/05/03 Python
基于tf.shape(tensor)和tensor.shape()的区别说明
2020/06/30 Python
Python 使用生成器代替线程的方法
2020/08/04 Python
html5 css3 动态气泡按钮实例演示
2012/12/02 HTML / CSS
英国家庭和商业健身器材购物网站:Fitness Options
2018/07/05 全球购物
德国网上超市:myTime.de
2019/08/26 全球购物
银行求职信
2014/05/31 职场文书
没有孩子的离婚协议书怎么写
2014/09/17 职场文书
企业党的群众路线教育实践活动领导班子对照检查材料
2014/09/25 职场文书
Golang二维数组的使用方式
2021/05/28 Golang
教你使用Python获取QQ音乐某个歌手的歌单
2022/04/03 Python
六个好看实用的 HTML + CSS 后台登录入口页面
2022/04/28 HTML / CSS
Python实现将多张图片合成MP4视频并加入背景音乐
2022/04/28 Python