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

一、ng-bing-html指令问题

需求:我需要将一个变量$scope.x = '<a href="http://www.baidu.com/">百度一下</a>'绑定到angular的视图上,希望视图上显示的一个链接. 

1.如果,我采用ng-bind="x",或者{{x}},我在视图看到的结果就是上面那个字符串,就说里面的“<”和“>”都被转义了.
2.如果,我在用ng-bind-html,视图上什么都没有,并且会抛出一个错误:"Attempting to use an unsafe value in a safe context."
问题来了,该怎么解决呢?

二、什么是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

三、$sce如何使用

1.将$sce用于指令编写(例1)

在指令值,一般需要操作dom,在添加元素时,如果要将传入的变量直接作为dom元素进行添加,就会可能会带来跨站风险,这时就需要,用$sce.getTrustedXXX从变量中获取受信任的数据。

例1:(这里的myTable指令需要插入html;x.data.Table是一段html的table字符串。)

html

<my-table table="x" ng-bind-html="x.data.Table | trustHtml"></my-table>

js

// 报表指令
app.directive("myTable", function () {
    return {
        restrict: 'AECM',
        template: '<div ng-transclude>{{cont}}</div>',
        replace: true,
        transclude: true,
        scope: {
            cont: '=table'
        }
    };
});

// 添加对html的信任 app.filter(
'trustHtml', function ($sce) { return function (input) { return $sce.trustAsHtml(input); } });

2.在controller中使用(例2)

例2:

<!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://map.baidu.com/");
            // $scope.trustSrc = $sce.trustAsResourceUrl("http://map.baidu.com/");//等同于这个方法
          }]);
    </script>
</body>
</html>
原文地址:https://www.cnblogs.com/fydxx/p/6627148.html