在全局启用的trustasresourceurl上下文中清理单个控制器中的资源

时间:2017-09-12 16:56:35

标签: angularjs

据我了解Angular中的$sce,默认行为是:

  

AngularJS将自动对[敏感HTML]运行安全检查   (清理,白名单,取决于上下文

另外,据我所知,白名单(通过$sceDelegateProvider.resourceUrlWhitelist)会阻止消毒。

基本上,我已经有了一个全局启用trustasresourceurl的应用程序(see accepted answer)。现在,我想从这个全局信任中排除1个控制器。换句话说,我希望将此内容显示为纯文本,而没有任何样式绑定到ng-bind-html

<span style="font-family: Arial; font-size: 24px;"> A wizard is never late hardcode.</span>

我可能需要创建一个过滤器来手动删除任何HTML,但我讨厌这样做只是为了回到默认的角度行为。用正则表达式解析HTML是丑陋而脆弱的。你有什么建议?

This code接近我想要的,但无论什么样式被删除,所以它无法正确重现问题。我猜测白名单失败了,所以它仍然被消毒了。

&#13;
&#13;
var mainMod = angular.module('MainApp', ['ngSanitize']);

mainMod.controller('MainCtrl', ['$scope',
    function ($scope) {
      $scope.text = '<p>Hello! <a href="#">Link</a></p>';
  
      $scope.htmlContent = '<span style="font-family: Arial; font-size: 24px;"> A wizard is never late.</span>';
}]);

angular.module('MainCtrl', []).config(function($sceDelegateProvider) {
  $sceDelegateProvider.resourceUrlWhitelist([
    // Allow same origin resource loads.
    'self',
    // Allow loading from our assets domain.  Notice the difference between * and **.
    'https://codepen.io/**'
  ]);

  // The blacklist overrides the whitelist so the open redirect here is blocked.  I don't want to blocklist the whole resource.  Just this one controller.
  $sceDelegateProvider.resourceUrlBlacklist([
    ''
  ]);
});
&#13;
body{
  padding:20px;
}
.search{
  margin-left:10px;
}
&#13;
<script src="https://code.angularjs.org/1.5.11/angular.min.js"></script>
<script src="https://code.angularjs.org/1.5.11/angular-sanitize.min.js"></script>

<body ng-app='MainApp'>
  <div ng-controller="MainCtrl">  
    <div ng-bind-html="htmlContent"></div>
    <div ng-bind-html='text'></div>   
    
    <span style="font-family: Arial; font-size: 24px;"> A wizard is never late hardcode.  In real app this is what I get.  </span>
  </div>
</body>
&#13;
&#13;
&#13;

Angular 1.5.11

2 个答案:

答案 0 :(得分:1)

过滤以从HTML获取文字:

mainMod.filter('get_text', ['$sce', function($sce){
    return function(text) {
         console.log("actual HTML",text)
         var doc = new DOMParser().parseFromString(text, "text/html");
        var   textVal= doc.documentElement.textContent;
        console.log(textVal,"Only Text")
        return $sce.trustAsHtml(textVal)
    };
}]);

并在HTML中:

 <div ng-bind-html="htmlContent|get_text"></div>

var mainMod = angular.module('MainApp', ['ngSanitize']);
    
mainMod.filter('get_text', ['$sce', function($sce){
    return function(text) {
         console.log("actual HTML",text)
         var doc = new DOMParser().parseFromString(text, "text/html");
        var   textVal= doc.documentElement.textContent;
        console.log(textVal,"Only Text")
        return $sce.trustAsHtml(textVal)
    };
}]);

mainMod.controller('MainCtrl', ['$scope',
    function ($scope) {
      $scope.text = '<p>Hello! <a href="#">Link</a></p>';
  
      $scope.htmlContent = '<span style="font-family: Arial; font-size: 24px;"> A wizard is never late.</span>';
}]);

angular.module('MainCtrl', []).config(function($sceDelegateProvider) {
  $sceDelegateProvider.resourceUrlWhitelist([
    // Allow same origin resource loads.
    'self',
    // Allow loading from our assets domain.  Notice the difference between * and **.
    'https://codepen.io/**'
  ]);

  // The blacklist overrides the whitelist so the open redirect here is blocked.  I don't want to blocklist the whole resource.  Just this one controller.
  $sceDelegateProvider.resourceUrlBlacklist([
    ''
  ]);
});
body{
  padding:20px;
}
.search{
  margin-left:10px;
}
<script src="https://code.angularjs.org/1.5.11/angular.min.js"></script>
<script src="https://code.angularjs.org/1.5.11/angular-sanitize.min.js"></script>

<body ng-app='MainApp'>
  <div ng-controller="MainCtrl">  
    <div ng-bind-html="htmlContent|get_text"></div>
    <div ng-bind-html='text'></div>   
    
    <span style="font-family: Arial; font-size: 24px;"> A wizard is never late hardcode.  In real app this is what I get.  </span>
  </div>
</body>

答案 1 :(得分:0)

如果您需要更多向后兼容性以及格式错误的HTML的灵活性,那么以下过滤器也可以使用:

mainMod.filter('get_text', ['', function(){
    //A more forgiving HTML to text conversion
    //Wrap the content in a div and get inner text
    return function(text) {
         var doc = document.createElement('div');
         doc.innerHTML = text;
         return doc.textContent;//no need to trustAsHtml because always plain text
    };
}]);