zoukankan      html  css  js  c++  java
  • AngularJS中的模板安全与作用域绑定

    欢迎大家指导与讨论 : )

      一、前言

        摘要:指令compile、$sce、作用域绑定、$compileProvider和其他资源安全设置本文是笔者在学习时整理的笔记,由于技术还不够高,如果本章中有错误的地方希望各位能够指出,共同进步O(∩_∩)O  

      二、compile与$compile

        二 . 1 指令中的compile

          指令的创建需要经历三大过程: compile(编译) -> preLink(链接作用域前) -> postLink(链接作用域后)。三大过程由前到后按顺序执行,当我们到达postLink(平时创建指令的link函数),就说明这个指令及其子模板都已经经过complie编译了(complie过程最先执行)。其中,complie过程能够访问element实例和element的属性并且只执行一次   compile: function(tElem, tAttrs){//...} 。由于在这个过程还没有进行element与作用域scope的链接并且只执行一次,因此在这个时候对DOM进行操作只有很小的性能开销。因此建议DOM的事件绑定放到complie阶段。而在postLink过程中,因为element已经和作用域绑定了,所以一些需要保证必须执行的代码可以放到link(postLink)中执行 function(scope, iElem, iAttrs){//...} 

        二 . 2 使用$compile服务进行作用域绑定

          $complie服务能够让我们的HTML模板与作用域进行绑定,当我们在指令中需要这么做的时候我们可以这样子写

    $compile(element.contents())(scope);
    //element.contents()表示为当前元素及其所有子元素

      三、$sce

        $sce是一个非常出色的服务,它允许我们编写黑白名单,默认保护代码,并在很大程度上帮助我们放在XSS和其他漏洞。像是指令中的templateUr、ng-bind-html或者ng-include也是默认使用这个服务

        三 . 1 模板安全与实例

          假设我们有如下需求:允许用户在编写HTML代码,并得到即时预览。我们希望angular能够允许受信任的内容返回并插入到DOM中。

    //html代码
    <input ng-model="userHtml">
    <div ng-bind-html="userHtml"></div>
    
    //指令代码
    var ngBindHtmlDirective = ['$sce', function($sce) {
      return function(scope, element, attr) {
        scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function(value) {
          element.html(value || '');
        });
      };
    }];

        三 . 2 模板加载来源与黑白名单 

          默认情况下,angular只允许我们在同一域中加载我们所需要的模板,但当我们有特殊需求时,我们通过$sceDelegateProvider.resourceUrlWhitelist()设置白名单来改变这个默认规则(可能需要服务端配合CORS来达到目的)。

          三 . 2. 1 当resourceUrlWhitelist中没有参数

            此方法变成getter方法,返回当前白名单数组

          三 . 2. 2 当resourceUrlWhitelist中参数为self

            angular会确保我们所要下载的模板在应用的同一域下

          三 . 2. 2 当resourceUrlWhitelist中参数为其他正则表达式

            angular会匹配资源所对应的绝对URL

    angular.module('app', [])
        .config(['$sceDelegateProvider', function($sceDelegateProvider){
           $sceDelegateProvider.resourceUrlWhitelist(['.*])
    }])   

        三 . 3 资源安全$compileProvider

          三 . 3 . 1 链接资源安全 aHrefSanitizationWhitelist

            笔者在做小项目的时候遇到过,自定义的链接在view中被渲染的时候被angular加上了不信任标记,导致不能正常使用

            通过设置资源白名单来解决这个问题(注:参数使用正则表达式)

    app.config(['$compileProvider' , function ($compileProvider)
        {
           $compileProvider.aHrefSanitizationWhitelist(/^s*(https?|ftp|mailto|chrome-extension|app):/);
        }]);

          三 . 3 . 1 图片资源安全 imgHrefSanitizationWhitelist(同上)

      四、官网实例

    //html
    <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>
    
    //js
    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>');
      }]);
    
    //data.json
    [
      { "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?"
      }
    ]

       、资料参考

      《ngBook》 P385

       官方文档 http://docs.angularjs.cn/api/ng/service/$sce

      其他博客(强烈推荐) http://www.ifeenan.com/angularjs/2014-09-04-%5B译%5DNG指令中的compile与link函数解析/

     

     

  • 相关阅读:
    dapper 可空bool转换出错及解决方案
    python监控linux内存并写入mongodb
    MongoDB 线上环境按照及配置(授权方式启动)
    工作吐槽
    visual studio 调试grunt
    require js 将config和入口函数分开写
    【转】Contrary to the answers here, you DON'T need to worry about encoding!
    [ 转]国内有时抽风,无法更新adt的解决方案
    The ToolStripMenuItem visible value always false
    ArcGis : unable to save as template this document is already based on another template
  • 原文地址:https://www.cnblogs.com/BestMePeng/p/AngularJS_Sce.html
Copyright © 2011-2022 走看看