ng-bind-html & $sce学习笔记

ng-bind-html & $sce学习笔记

May 26, 2016
Angular1.4

#ng-bind-html & $sce学习笔记

注意事项: 用该指令bind内容时,必须依赖ngSanitize模块,同时调用$sce.trustAsHtml等方法,否则会出现 Attempting to use an unsafe value in a safe context. 异常

ng-bind-html源码

注意: 可以发现内部是调用的$sce.getTrustedHtml 方法

var ngBindHtmlDirective = ['$sce', function($sce) {
  return function(scope, element, attr) {
    element.addClass('ng-binding').data('$binding', attr.ngBindHtml);
    scope.$watch(attr.ngBindHtml, function ngBindHtmlWatchAction(value) {
      element.html($sce.getTrustedHtml(value) || '');
    });
  };
}];

trustAs Vs getTrusted

理解不是透彻,先把想法写一下

官方代码Code

<div ng-controller="AppController as myCtrl">
  <i ng-bind-html="myCtrl.explicitlyTrustedHtml" id="explicitlyTrustedHtml"></i><br><br>
  <b>User comments</b><br>
  By default, HTML that isn't explicitly trusted (e.g. Alice's comment) is sanitized when
  $sanitize is available.  If $sanitize isn't available, this results in an error instead of an
  exploit.
  <div class="well">
    <div ng-repeat="userComment in myCtrl.userComments">
      <b>{{userComment.name}}</b>:
      <span ng-bind-html="userComment.htmlComment" class="htmlComment"></span>
      <br>
    </div>
  </div>
</div>
angular.module('mySceApp', ['ngSanitize'])
.controller('AppController', ['$http', '$templateCache', '$sce',
  function($http, $templateCache, $sce) {
    var self = this;
    $http.get("test_data.json", {cache: $templateCache}).success(function(userComments) {
      self.userComments = userComments;
    });
    self.explicitlyTrustedHtml = $sce.trustAsHtml(
        '<span onmouseover="this.textContent=&quot;Explicitly trusted HTML bypasses ' +
        'sanitization.&quot;">Hover over this text.</span>');
  }]);
[
  { "name": "Alice",
    "htmlComment":
        "<span onmouseover='this.textContent=\"PWN3D!\"'>Is <i>anyone</i> reading this?</span>"
  },
  { "name": "Bob",
    "htmlComment": "<i>Yes!</i>  Am I the only other one?"
  }
]

完整代码例子

<!DOCTYPE html>
<html ng-app="bindSceModule">

<head>
    <title>ng-bind-html--$sce</title>
    <script type="text/javascript" src="../bower_components/angular/angular.js"></script>
    <script type="text/javascript" src="../bower_components/angular-sanitize/angular-sanitize.min.js"></script>
    <script type="text/javascript">
    angular.module('bindSceModule', ['ngSanitize'])
        .controller('SceController', ['$scope', '$sce', '$http', '$templateCache',
            function($scope, $sce, $http, $templateCache) {
                var self = this;
                $http.get('../data/test_sce.json').success(function(result) {
                    self.comments = result;
                });

                var html = '<span onmouseover="this.textContent=&quot;Explicitly trusted HTML bypasses ' +
                    'sanitization.&quot;">Hover over this text.</span>';

                self.html = html;
                self.trustedHtml = $sce.getTrustedHtml(html);
                self.explictTrustedHtml = $sce.trustAsHtml(html);
                self.myTrustedHtml = $sce.getTrustedHtml(self.explictTrustedHtml);
            }
        ])
        .directive('ngBindHtmlSafe', ['$compile', function($compile) {

            return {
                link: function(scope, element, attrs, controller) {
                    var compile = function(html) {
                        var htmlDom = $compile(html)(scope);
                        element.html('').append(htmlDom);
                    };

                    var htmlName = attrs.ngBindHtmlSafe;

                    scope.$watch(htmlName, function(newHtml) {
                        if (!newHtml) return;
                        compile(newHtml);
                    });
                }
            };
        }]);
    </script>
</head>

<body ng-controller="SceController as sceCtrl">
    <i ng-bind-html="sceCtrl.explictTrustedHtml"></i>
    <br>
    <i ng-bind-html="sceCtrl.trustedHtml"></i>
    <br>
    <i ng-bind-html="sceCtrl.html"></i>
    <br>
    <i ng-bind-html-safe="sceCtrl.myTrustedHtml"></i>
    <br>
    <div ng-repeat="comment in sceCtrl.comments">
        <b>{{comment.name}}</b>
        <span ng-bind-html="comment.htmlComment"></span>
        <br>
    </div>
</body>

</html>


Written with StackEdit.

select学习笔记

May 26, 2016
Angular1.4

rootScope.Scope学习笔记

May 26, 2016
Angular1.4

no-cloak学习笔记

May 26, 2016
Angular1.4