【问题标题】:angularJS How can I ignore certain HTML tags?angularJS 如何忽略某些 HTML 标签?
【发布时间】:2014-03-20 12:45:48
【问题描述】:

我收到此错误是因为其中一位用户在他的帖子中添加了<3

错误:[$sanitize:badparse] sanitizer 无法解析以下 html 块:

我写的代码是ng-bind-html ="Detail.details"

我希望他只被带上<a>标签和标签<br />

这可能吗?

谢谢!

【问题讨论】:

标签: html angularjs tags


【解决方案1】:

您可以创建过滤器来清理您的 html。

我在其中使用了 strip_tags 函数 http://phpjs.org/functions/strip_tags/

angular.module('filters', []).factory('truncate', function () {
    return function strip_tags(input, allowed) {
      allowed = (((allowed || '') + '')
        .toLowerCase()
        .match(/<[a-z][a-z0-9]*>/g) || [])
        .join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
      var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
        commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
      return input.replace(commentsAndPhpTags, '')
        .replace(tags, function($0, $1) {
          return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
        });
    }
});

控制器:

angular.module('myApp', ['filters'])
.controller('IndexController', ['$scope', 'truncate', '$sce', function($scope, truncate, $sce){
  $scope.text="";

  $scope.$watch('text', function(){
    $scope.sanitized = $sce.trustAsHtml(truncate($scope.text, '<a><br>'));
  });
}]);

查看:

<div ng-bind-html="sanitized"></div>

http://plnkr.co/edit/qOuvpSMvooC6jR0HxCNT?p=preview

【讨论】:

  • 是否可以不替换错误的标签但显示它们?例如,在您的 plunker 中,没有 标签,只显示 Bold sanitized?
【解决方案2】:

我遇到了同样的问题并使用$sce.trustAsHtml 修复了它,请参阅此

$scope.body = $sce.trustAsHtml(htmlBody);

// In html
<div ng-bind-html="body">body</div>

解决问题

【讨论】:

  • 我认为这是个坏主意。然后,您将绕过 ngSanitize 安全检查。因此,您可能会打开您的应用程序以遭受 HTML 注入攻击。
  • 看我没有使用ng-bind-html-unsafe,它被贬低了,你不能在没有ngSanitize的情况下使用ng-bind-html。所以不存在安全问题。
【解决方案3】:

要保留现有的ng-bind-html 行为而不崩溃,您可以捕获$sanitize:badparse 异常。

ngBindHtml component 在内部使用 ngSanitize service。将$sanitize 注入您的控制器并捕获它。

$sce.trustAsHtml 方法相比,此方法的优势在于$sanitize 不会引入任何潜在的安全漏洞(例如javascript 注入)。

控制器(注入$sanitize):

$scope.clean = function (string) {
    $scope.clean = function(string) {
        try {
            return $sanitize(string);
        } catch(e) {
            return;
        }
    };
};

这个方法可以通过缓存最后一个已知的好值来改进。

查看:

<div ng-bind-html="clean(body)"></div>

【讨论】: