angular.jsをやってみる (13) - $sceとngSanitize -

2014-03-28T00:00:00+00:00 angular.js JavaScript

※ややこしいので公式ドキュメント読んだ方がいい

<div ng-controller="SampleController">
  <span>{% raw %}{{message}}{% endraw %}</span>
</div>

的な感じになってて

angular.module("app", [])
  .controller("SampleController", function($scope) {
    $scope.message = '<span style="color: red">hoge</span>';
  });

みたいにすると、$scopeとかに含まれるHTMLとかはエスケープされて出力されるらしい

<div ng-controller="SampleController">
  <span ng-bind-html="message" />
</div>

みたいにすると「Error: $sce:unsafe」っていうエラーになる模様。但し、このエラーが発生するのはangular-sanitize.jsが参照されていない場合であって参照されている場合などにおいては物によっては出力は許可されるがCSP(Content Security Policy)に反するようなインラインなスタイルやスクリプトは除去される模様。あくまで汚染物を除去する的な所かと

ちょっと余談が多いけど、それの出力を許可するようにするには$sce(Strict Contextual Escaping)を使う事で出来る模様。あくまで$sceはangular-sanitizeに含まれる物では無い模様

angular.module("app", [])
  .controller("SampleController", function($scope, $sce) {
    var text = '<span style="color: red">hoge</span>';
    $scope.message = $sce.trustAsHtml($text);
  });

$sceで使えるAPIについてはhttp://docs.angularjs.org/api/ng/service/$sceを参照

若干ややこしいが

  • $scopeに突っ込んだHTMLはエスケープされて出力される
  • angular-sanitize.jsを参照せずにng-bind-htmlでHTMLをバインドしようとするとエラーが出る
  • angular-sanitize.jsを参照してng-bind-htmlでHTMLをバインドすると出力されるが、CSPに反するような部分は除去される
  • $sceのAPIを使う事でCSPに反するようなのを除去せずにHTMLとして出力する事が可能(但し、許可されないのもある)

っていう感じかと。んまぁセキュリティ観点からするとむやみに$sce.trustAsHtmlとかしないようにするべきなのが一番良いのだろうと。

余談: linkyフィルターについて

angular-sanitize.jsのドキュメントによるとデータ中のURL等をマークアップ化する方法としてはlinkyフィルターを使えば良い模様

<div ng-controller="SampleController">
  <span ng-bind-html="message | linky" />
</div>

的な感じにして

angular.module("app", ["ngSanitize"])
  .controller("SampleController", function($scope) {
    $scope.message = "http://localhost";
  });

的な感じでURL等が含まれるデータはlinkyフィルターによってマークアップされる模様

んまぁ詳しいことはドキュメント(http://docs.angularjs.org/api/ngSanitize/filter/linky)読めって事で

SwipeRefreshLayout angular.jsをやってみる (12) - angular-mocks.jsを使ったテスト -