ng-bind-html-unsafeを削除して、HTMLを挿入するにはどうすればよいですか?


265

私が使用しようとしている$sanitizeプロバイダとng-bind-htm-unsafeDIVの中に注入HTMLへの私のコントローラを許可するように指示を。

しかし、私はそれを機能させることができません。

<div ng-bind-html-unsafe="{{preview_data.preview.embed.html}}"></div>

AngularJSから削除されたからだとわかりました(ありがとう)。

しかし、なしでng-bind-html-unsafe、私はこのエラーを受け取ります:

http://errors.angularjs.org/undefined/$sce/unsafe


1.2.23以降の簡単な解決策があります。投稿を参照してください
John Henckel

回答:


123
  1. sanitize.jsがロードされていることを確認する必要があります。たとえば、https://ajax.googleapis.com/ajax/libs/angularjs/ [LAST_VERSION] /angular-sanitize.min.jsからロードします。
  2. あなたngSanitizeはあなたのapp eg にモジュールを含める必要があります:var app = angular.module('myApp', ['ngSanitize']);
  3. ng-bind-html元のhtmlコンテンツにバインドする必要があるだけです。コントローラで他に何もする必要はありません。解析と変換はngBindHtmlディレクティブによって自動的に行われます。(How does it workこれに関するセクションを読んでください:$ sce)。だから、あなたのケースで<div ng-bind-html="preview_data.preview.embed.html"></div>は仕事をします。

3
それを安全に行うことが最もクリーンなオプションです。より多くの依存関係が付属していますが、それは安全に関するものなので、ためらうことはありません!
Pierre Maoui 2014

これをionic 1.0.0-beta.13で使用する
jasonflaherty

3
これは、入力などの一部のタグでは機能しません。もちろん、これを回避する簡単な方法はありません。本当にイライラします。
ケーシー

最も一般的で安全な方法。異なるビューでbind-htmlを使用する予定がある場合は、これをお勧めします。
エドゥアルドブルサ2015年

350

Alexによって提案されているように、スコープ内で関数を宣言する代わりに、単純なフィルターに変換できます。

angular.module('myApp')
    .filter('to_trusted', ['$sce', function($sce){
        return function(text) {
            return $sce.trustAsHtml(text);
        };
    }]);

その後、次のように使用できます。

<div ng-bind-html="preview_data.preview.embed.html | to_trusted"></div>

そしてここに実際の例があります:http : //jsfiddle.net/leeroy/6j4Lg/1/


3
私はgithubの Angularに役立つツールの小さなコレクションを持っています。よろしければ、これらのツールにこのフィルターを含めます。これは、HTMLを信頼するときの最良の解決策です。
Capaj 2014

@Capaj問題ありませんが、この回答へのリンクを追加すると、非常に役立ちます。:-) stackoverflow.com/a/21254635
Leeroy Brun

非常に素晴らしい。これはネストされた繰り返しの魅力のように機能します!
Jelle Verzijden 2015

これは、各コントローラーのコーディングよりもはるかに優れたソリューションのようです。簡単なフィルターで完了です!パイのように単純な繰り返しテーブル行で使用しました... <td ng-bind-html="representative.primary | to_trusted"></td>
Phil Nicholas

2
angular.module( 'myApp')。filter( 'trustAsHtml'、['$ sce'、function($ sce){return $ sce.trustAsHtml}]);
bradw2k 2015

275

Angular 1.2.0を使用しているとのことですが、他のコメントの1つとしてng-bind-html-unsafe非推奨になりました。

代わりに、次のようなことをしたいと思うでしょう:

<div ng-bind-html="preview_data.preview.embed.htmlSafe"></div>

コントローラで、$sceサービスを注入し、HTMLを「信頼できる」としてマークします。

myApp.controller('myCtrl', ['$scope', '$sce', function($scope, $sce) {
  // ...
  $scope.preview_data.preview.embed.htmlSafe = 
     $sce.trustAsHtml(preview_data.preview.embed.html);
}

1.2.0-rc3以降を使用する必要があることに注意してください。(彼らはrc3のバグを修正し、「ウォッチャー」が信頼できるHTMLで適切に動作するのを妨げていました。)


2
上記を使用してみましたが、コードが壊れます。関数定義の前に '$ scope'を付加する必要があるようです-おそらくそれは一度に「理解された」が、もはや理解されなかったでしょう。次の作業をする必要があります:myApp.controller('myCtrl', ['$scope', '$sce', function($scope, $sce) {
Dexygen

4
好奇心を追求するためだけに$ sceに関する詳細情報をここで見ることができます!;)
本物のファファ2014

5
これにより、コードでXSSセキュリティ問題が発生する可能性があることに注意してください。代わりのより安全な修正については、ngSanitize以下の提案(stackoverflow.com/a/25679834/22227)を参照してください。
Martin Probst 2016年

なぜこれが悪い考えです:docs.google.com/presentation/d/...
user857990

trustAsHtmlそれが言うことを行う、それはクロスサイトスクリプティング(XSS)攻撃を
引き起こす

112

私にとって、最も単純で最も柔軟なソリューションは次のとおりです。

<div ng-bind-html="to_trusted(preview_data.preview.embed.html)"></div>

そして、コントローラに関数を追加します。

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

$sceコントローラの初期化に追加することを忘れないでください。


コントローラーが信頼できるHTMLを$ scopeに返すようにするほうが簡単なようです
meffect

1
これにより、$ sceに無限ループが発生する可能性があります。次のようにします。$ scope.trusted = {}; $ scope.to_trusted = function(html_code){return $ scope.trusted [html_code] || ($ scope.trusted [html_code] = $ sce.trustAsHtml(html_code)); };
AO_ 14

1
HTMLを信頼できるものとして祝福することを含むすべてのソリューションは、XSSの脆弱性をもたらします。より安全な修正については、以下のngSanitizeを提案する回答(stackoverflow.com/a/25679834/22227)を参照してください。
Michele Spagnuolo 2016

65

私の意見ではこれに対する最良の解決策はこれです:

  1. たとえばcommon.module.jsファイルに含めることができるカスタムフィルターを作成します-アプリ全体で使用します。

    var app = angular.module('common.module', []);
    
    // html filter (render text as html)
    app.filter('html', ['$sce', function ($sce) { 
        return function (text) {
            return $sce.trustAsHtml(text);
        };    
    }])
  2. 使用法:

    <span ng-bind-html="yourDataValue | html"></span>

さて、なぜディレクティブng-bind-htmltrustAsHtmlその機能の一部として含まれていないのかわかりません-私には、それがそうではないというのは少しふさわしいようです

とにかく-それが私のやり方です-67%の確率で、いつでも機能します。


次の正規表現を使用して検索と置換を行うことができます:regex:ng-bind-html-unsafe = "((?:( ?!")。)*) "置換:ng-bind-html ="($ 1) | 上記のフィルターを使用したhtml "
George Donev

2
HTMLを信頼できるものとして祝福することを含むすべてのソリューションは、XSSの脆弱性をもたらします。より安全な修正については、以下のngSanitizeを提案する回答(stackoverflow.com/a/25679834/22227)を参照してください。
Michele Spagnuolo 2016

7

もちろん、安全でない独自のHTMLバインディングを作成することもできますが、ユーザー入力を使用する場合は、セキュリティリスクになる可能性があります。

App.directive('simpleHtml', function() {
  return function(scope, element, attr) {
    scope.$watch(attr.simpleHtml, function (value) {
      element.html(scope.$eval(attr.simpleHtml));
    })
  };
})

このディレクティブでも$sce.trustAsHtml?を使用できませんでしたか?
kontur 2014

5

ng-bind-html-unsafe内で{{}}を使用する必要はありません。

<div ng-bind-html-unsafe="preview_data.preview.embed.html"></div>

次に例を示します。http//plnkr.co/edit/R7JmGIo4xcJoBc1v4iki?p = preview

{{}}演算子は基本的にng-bindの省略形にすぎないため、試みていたものはバインディング内のバインディングに相当し、機能しません。


しかし、それを取り除くと、何も注入されません。そして、ドキュメントは1つの} docs-angularjs-org-dev.appspot.com/api/…
2013年

非常に奇妙な。私はちょうどそれを確かめるためにそれをテストしました、そして私にとってそれは期待通りに機能しました。単一の{}はドキュメントで少し混乱することに同意しますが、それらは文字列内のリテラルとしてではなく、式の表現として意図されています。動作するプランクで回答を更新しました。
ksimons 2013年

あなたはNG-バインド-HTML-安全ではないとして、ここでコメントを参照してください、すでに1.2.0を使用している場合も、削除されました:docs.angularjs.org/api/ng.directive:ngBindHtmlを
ksimons

2
1.2を使用しています。:( Grrr!安全でないHTMLを挿入するにはどうすればよいですか?このエラーなしでこのエラーが発生します:errors.angularjs.org/undefined/$sce/unsafe
metalaureate 2013年

{{}}オペレータは、失敗結合でヒントのおかげで、私の問題を引き起こしていました!
Campbeln 2014

2

同様の問題がありました。それでも、githubでホストされているマークダウンファイルからコンテンツを取得できませんでした。

app.jsの$ sceDelegateProviderに(githubドメインが追加された)ホワイトリストを設定した後、それは魅力のように機能しました。

説明:別のURLからコンテンツをロードする場合、信頼できるものとしてラップするのではなく、ホワイトリストを使用します。

ドキュメント: $ sceDelegateProviderngInclude(外部HTMLフラグメントの取得、コンパイル、インクルード用)


2

厳格なコンテキストエスケープを完全に無効にして、を使用してHTMLを挿入できるようにすることができますng-html-bind。これは安全ではないオプションですが、テスト時には役立ちます。

$sceAngularJSドキュメントの例:

angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) {
  // Completely disable SCE.  For demonstration purposes only!
  // Do not use in new projects.
  $sceProvider.enabled(false);
});

上記の設定セクションをアプリに添付すると、htmlをng-html-bindに挿入できますが、ドキュメントのとおりです。

SCEを使用すると、コーディングのオーバーヘッドがほとんどなく、多くのセキュリティ上の利点が得られます。SCEが無効になっているアプリケーションを取得して自分で保護するか、後の段階でSCEを有効にするのははるかに困難です。SCEが導入される前に書かれた既存のコードがたくさんあり、それらを一度にモジュールに移行する場合は、SCEを無効にすることは理にかなっています。


知っておくと良いですが、間違いなく注意して処理する必要があります。
iconoclast

2

このようなフィルターを使用できます

angular.module('app').filter('trustAs', ['$sce', 
    function($sce) {
        return function (input, type) {
            if (typeof input === "string") {
                return $sce.trustAs(type || 'html', input);
            }
            console.log("trustAs filter. Error. input isn't a string");
            return "";
        };
    }
]);

使用法

<div ng-bind-html="myData | trustAs"></div>

他のリソースタイプ、たとえばiframeのソースリンクやここで宣言された他のタイプに使用できます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.