28

テキストでHTMLエスケープを行うAngularJSコマンドはありますか?カスタムディレクティブを処理していて、それが生成する出力の一部をエスケープする必要があります。

内部的には、AngularJS sanitzerはencodeEntities関数を使用しますが、それを公開しません。関数を複製できることは知っていますが、これを行うための標準的な方法があるはずです。


ユースケース:言語のローカリゼーションを行うカスタムディレクティブがあります。このディレクティブは、データファイルからのキールックアップを使用して言語テキストを検索します。場合によっては、このテキストにHTMLを含めることが許可されているか、ディレクティブがHTMLを生成して、結果の視覚的なフォーマットを改善します。さらに、このディレクティブはAngular式をパラメーターとして受け取り、それらを文字列内のトークンの代わりとして使用します。これらのパラメータはHTMLで安全ではない可能性があるため、エンコードする必要があります。

ディレクティブは、たとえば、属性として呼び出されますi18n-html='welcome_text_html,1+1,user.name'。次に、ディレクティブは説明されているように文字列をフォーマットしelement.html、DOMノードを更新するために使用します。

4

9 に答える 9

29

この回答は、 HTMLのサニタイズではなく、エスケープに関するものです。次の 2 つの方法があります。

  1. @maniekq が述べたように、DOM で作業できる場合は、次のようにします。

    element.text( scope.myValue );
    
  2. この回答から、mustache.js のこのコードを使用して、角度フィルターを作成できます。

    angular.module('myModule').filter('escapeHtml', function () {
    
        var entityMap = {
            "&": "&",
            "<": "&lt;",
            ">": "&gt;",
            '"': '&quot;',
            "'": '&#39;',
            "/": '&#x2F;'
        };
    
        return function(str) {
            return String(str).replace(/[&<>"'\/]/g, function (s) {
                return entityMap[s];
            });
        }
    });
    
于 2015-02-16T09:12:59.193 に答える
1

HTML のエスケープには、2 つの別個の問題があります。1 つ目の問題は、エンティティをエンコードする必要があることです。2 つ目の問題は、データを html バインディングとして使用できるように、結果を信頼する必要があることです。次のコードをコントローラーに追加すると、$sce サービスを使用して両方の問題を解決できます。

CoffeeScript ソリューション:

MyApp.controller('MyController', ['$scope','$sce',($scope,$sce) ->

  ###
  ...
  ###

  $scope.html5Entities = (value) ->
    value.replace(/[\u00A0-\u9999<>\&\'\"]/gim, (i) ->
      '&#' + i.charCodeAt(0) + ';'
    )

  $scope.trustAsHtml = (value) ->
    $sce.trustAsHtml(value)

  ###
  ...
  ###

])    


Javascript ソリューション:

MyApp.controller('MyController', ['$scope','$sce', function($scope,$sce) {

  /* ... */

  $scope.html5Entities = function(value) {
    return value.replace(/[\u00A0-\u9999<>\&\'\"]/gim, function(i) {
          return '&#' + i.charCodeAt(0) + ';'
        })
  };

  $scope.trustAsHtml = function(value) {
     return $sce.trustAsHtml(value);
  };

  /* ... */

}]);


最初の関数html5Entitiesは実際のエンティティ エンコーディングを行いますが、2 番目の関数trustAsHtmlは文字列を HTML バインディング用に Angular で安全に使用できるものとしてマークします。どちらのバージョンでも、コントローラに $sce サービスが含まれている必要があります。

使用例:

<div ng-bind-html="trustAsHtml((html5Entities(product.title) | highlight: $select.search))"></div>

関連する問題を参照してください:

于 2015-02-17T01:31:05.640 に答える
0

これは単純な解決策ではありませんが、Angular-sanitize コードに飛び込むと、 function を見つけることができますencodeEntities。素敵だけどプライベート。の使用法を探すには、 に移動してからhtmlSanitizeWriterに移動しsanitizeTextます。まだ非公開ですが、パブリック フィルターで使用されますlinky

明示的に使用linkyしてリンクが見つからないことを期待するか、サービスを再実装sanitizeTextまたはencodeEntitiesint することができます。

于 2016-12-01T16:30:30.417 に答える
0

AngularJS で HTML サニタイズを行う方法は 2 つあります。1 つ目は ngBindHtml ディレクティブを使用する方法で、2 つ目は $sanitize サービスを使用する方法です。

function MyCtrl ( $scope, $sanitize ) {
  $scope.rawHtml = "<div><script></script></div>";
  $scope.sanitizedHmtl = $sanitize( $scope.rawHtml );
}

次に、これら 2 つは機能的に同等です。

<div ng-bind-html="rawHtml"></div>
<div ng-bind-html-unsafe="sanitizedHtml"></div>

質問のようにディレクティブで使用する場合は、サニタイズされた HTML を挿入するだけです。

element.html( scope.sanitizedHtml );

しかし、ほとんどの場合、ディレクティブを記述するときは、これをテンプレートに入れ、上記のように ngBindHtml を使用します。ただし、コーナーケースでは機能します。

于 2013-01-25T02:16:45.120 に答える