AngularJSコントローラーからビューにHTMLを挿入する


800

HTMLを作成することは可能ですかAngularJSコントローラーでフラグメントこのHTMLをビューに表示することは可能ですか?

これは、一貫性のないJSON blobをネストされたid: valueペアのリストに変換する必要があるためです。したがって、HTMLはコントローラーで作成され、表示しようとしています。

モデルプロパティを作成しましたが、HTMLを印刷するだけではビューに表示できません。


更新

問題は、作成されたHTMLを引用符で囲まれた文字列として角度レンダリングすることから発生するようです。これを回避する方法を見つけようとします。

コントローラーの例:

var SomeController = function () {

    this.customHtml = '<ul><li>render me please</li></ul>';
}

ビューの例:

<div ng:bind="customHtml"></div>

与える:

<div>
    "<ul><li>render me please</li></ul>"
</div>

1
また、挿入されたHTMLのスクリプトを実行することが可能かどうかを尋ねるこの質問を参照しください。

複数のオブジェクトを同じng-bindにバインドすることは可能ですか?`` `ng-bind =" site.address_1 site.address_2 site.zip "
fauverism

ページに多くのものがある場合、angular.js(狂気)の15046行目を変更する必要がありますfunction htmlSanitizer(html) {...。Angular開発者は、すべてのページの非表示要素を1つずつゆっくりと調べて、HTMLの1つの欠落している部分を見つけることで、任意のhtmlバインディングを見つけることができるはずであると判断しました。!!! そのような仮定に非常に怒っています!!!
user3338098

申し訳ありませんが、ルークによって選択された答えは完全に正しい答えではない可能性があります。正しい答えは、こちらの別の質問にあります。基本的に、「ng-bind-html-unsafeはコンテンツをHTMLとしてレンダリングするだけです。Angularスコープを結果のDOMにバインドしません。そのためには$ compileサービスを使用する必要があります。」
gm2008

ng-bindはすべての内部htmlを削除します。これはフィルターが機能する方法ではなく、フィルターが唯一の値である場合は問題ありません
Muhammad Umer

回答:


1120

Angular 1.xの場合ng-bind-htmlは、HTML で使用します。

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

この時点でattempting to use an unsafe value in a safe contextエラーが発生するため、ngSanitizeまたは$ sceを使用して解決する必要があります。

$ sce

$sce.trustAsHtml()コントローラで使用して、html文字列を変換します。

 $scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml(someHtmlVar);

ngSanitize

2つのステップがあります。

  1. angular-sanitize.min.jsリソースを含めます。
    <script src="lib/angular/angular-sanitize.min.js"></script>

  2. jsファイル(コントローラーまたは通常はapp.js)に、ngSanitizeを含めます。
    angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngSanitize'])


30
Angular 1.2では、ng-bind-html-unsafeが削除され、2つのディレクティブが結合されました。参照:github.com/angular/angular.js/blob/master/...
サーシャChedygov

60
ngSanitizeを使用せずに、を使用して実行できるようになりました$sce。それをコントローラーに注入し、htmlを通過させます。$scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml(someHtmlVar);それ以外の場合はattempting to use an unsafe value in a safe context
引き続き

3
ここで少しクリーンアップが必要です。これは、何も機能していないように見える正しい方法です。
2014年


7
人々が落胆しないように、回答の最後にあるngSanitize要件と相まって、この回答の最新の更新が実際に機能します。
Ben Cull、2014

312

次のようにフィルターを作成することもできます。

var app = angular.module("demoApp", ['ngResource']);

app.filter("trust", ['$sce', function($sce) {
  return function(htmlCode){
    return $sce.trustAsHtml(htmlCode);
  }
}]);

次に、ビューで

<div ng-bind-html="trusted_html_variable | trust"></div>

:このフィルターは、渡されたすべてのhtmlを信頼します。ユーザー入力のある変数が渡された場合、XSSの脆弱性をもたらす可能性があります。


@Katie Astrauskas、回答ありがとうございます!とてもきれいな方法です。BTW ngResourceへの依存は必須ではありません。
アスラン2015年

28
HTMLを完全に信頼できる場合にのみ使用してください。これは、いかなる方法でもHTMLをサニタイズしませんが、AngularがHTMLをページに挿入できるようにするだけです。悪意のあるHTMLはXSS攻撃を引き起こす可能性があります。
jan.vdbergh 2015

パフォーマンスが重要な場合は、フィルターの使用を避けてください。フィルターは毎回2つのダイジェストをトリガーします。
タンテロープ

14
フィルターが呼び出されるのはなぜsanitizeですか?これは実際には何もサニタイズしないため、誤解を招く可能性があります。その代わりに呼ばれるべきtrusttrustSafeまたは類似した何か。
Denis Pshenov 2015年

1
素晴らしい答え。rawHtmlはの代わりにフィルタの名前ですsanitize
Wumms

119

Angular JSはタグ内にHTMLを表示します

上記のリンクで提供されているソリューションは私にとってはうまくいきましたが、このスレッドのオプションはどれもうまくいきませんでした。AngularJSバージョン1.2.9で同じものを探している人のために

ここにコピーがあります:

OKこれの解決策を見つけました:

JS:

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

HTML:

<p ng-bind-html="renderHtml(value.button)"></p>

編集:

これが設定です:

JSファイル:

angular.module('MyModule').controller('MyController', ['$scope', '$http', '$sce',
    function ($scope, $http, $sce) {
        $scope.renderHtml = function (htmlCode) {
            return $sce.trustAsHtml(htmlCode);
        };

        $scope.body = '<div style="width:200px; height:200px; border:1px solid blue;"></div>'; 

    }]);

HTMLファイル:

<div ng-controller="MyController">
    <div ng-bind-html="renderHtml(body)"></div>
</div>

7
HTMLが信頼できることを完全に確認する必要があることに注意してください。それ以外の場合は、XSS攻撃に対してドアが広く開かれています。
jan.vdbergh 2015

関数を使用してHTMLをレンダリングするこのソリューションは、私のために機能した唯一のものです。
MarceloBarbosa 2017年

「$ http」とは何ですか?
Soldeplata Saketos 2017

@SoldeplataSaketos特に何もありませんでした。当時はローカルで試していたので、依存関係をコピーしてしまいました。
anpatel 2017


65

幸いなことに、そのエラーメッセージを回避するために、派手なフィルターや安全でないメソッドは必要ありません。これは、意図した安全な方法でビューにHTMLマークアップを適切に出力するための完全な実装です。

Angularの後にsanitizeモジュールを含める必要があります:

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular-sanitize.js"></script>

次に、モジュールをロードする必要があります。

angular.module('app', [
  'ngSanitize'
]);

これにより、コントローラやディレクティブなどからの文字列にマークアップを含めることができます。

scope.message = "<strong>42</strong> is the <em>answer</em>.";

最後に、テンプレートでは、次のように出力する必要があります。

<p ng-bind-html="message"></p>

予想される出力が生成されます:42答えです。


1
次のようなhtmlを試してみてください<div><label>Why My Input Element Missing</label><input /></div>...意外な場合は、回答を更新してください。10個以上の投票ソリューションをすべてテストしたので..私の入力タグを表示するためのソリューションが機能しませんでした。$sce.trustAsHtml(html)
サミ

このソリューションは機能しますが、jsfiddleまたはplunkrを投稿しますか?
Pier-Luc Gendreau、2015

最新の角度を使用する場合、これは本当に答えになるはずです
Sandeep

61

私は今日試しました、私が見つけた唯一の方法はこれです

<div ng-bind-html-unsafe="expression"></div>


6
このソリューションは、クロスサイトスクリプティング攻撃を回避するためにソースが信頼できる場合にのみ使用してください。
Bertrand

3
Angular 1.0.2以降、これは私にとってはうまくいき、他のファイルやフックアップは必要ありません。

1
Angular 1.0.8を使用して、これは私のために働いた。ただし、@ Bertrandの警告に注意してください。必ずソースを信頼してください。
Jack Slingerland、2013年

12
将来の参考のために、ng-bind-html-unsafeはバージョン1.2で削除されました。ここでngSanitizeモジュールが必要です。安全でないhtmlをバインドするには、$ sce.trustAsHtmlメソッドを使用する必要があります。
Lucas Lazaro

53

ng-bind-html-unsafe 動作しなくなりました。

これが最短の方法です。

フィルターを作成します。

myApp.filter('unsafe', function($sce) { return $sce.trustAsHtml; });

そしてあなたの見解では:

<div ng-bind-html="customHtml | unsafe"></div>

PSこの方法では、ngSanitizeモジュールを含める必要はありません。


3
これは、Angular 1.2でここで見た中で最高のソリューションです。$sce受け入れられた回答で使用する解決策は私にとってはうまくいかなかったので、些細なことに依存関係を追加したくありませんでした。
Daniel Bonnell 2016年

Bidhan Bhattaraiの解決策がうまくいきました。Angular 1.6.1
mediaguru 2017

25

html

<div ng-controller="myAppController as myCtrl">

<div ng-bind-html-unsafe="myCtrl.comment.msg"></div>

または

<div ng-bind-html="myCtrl.comment.msg"></div

コントローラ上

mySceApp.controller("myAppController", function myAppController( $sce) {

this.myCtrl.comment.msg = $sce.trustAsHtml(html);

とも動作します $scope.comment.msg = $sce.trustAsHtml(html);


1
$sceきちんとしていますが、ユーザーがここにブレークポイントを追加し、悪意のあるコードをthis.myCtrl.comment.msgデバッガーを使用して復元することはできませんか?
BradGreens 14

次に、BradGreensですが、ng-bind-html-unsafeでも同じことができますか?
CodeOverRide 2014

4
誰かがそこに自分のブラウザをハッキングしたいのなら、誰も気にしない。他のユーザーには影響しません。@BradGreensそれは問題ですか?
Chris Stephens

@ChrisStephens、正解です。それは私の質問の答えになると思いますが、私の意見では、これらの機能は実際のセキュリティよりも知覚されるセキュリティに近いと思います。多分それはある種の自動化された攻撃から保護しますか?これを行うことがアプリに本当に役立つ理由を私は明確に理解したことがありません。私のアプリはwysiwyg HTMLをレンダリングするすべてのインスタンスにフィルターを追加する必要があります。インラインCSSが取り除かれるためng-bind-htmlです。
BradGreens 2014年

1
これらの機能は、安全なコーディングの間違いを減らすのに役立ちます。特に、マークアップ/コードインジェクションに関する問題。デフォルトでは、バインドされたすべてのデータが表示用にエンコードされます。したがって、基本的にマークアップを出力したい場合、これはあなたが何をしようとしているのかを考えることを余儀なくさせます。これらの機能がなければ、サーバー側のセキュリティだけでも多くのことを行うことができますが、懸念を分離するために、クライアントアプリは表示用にデータを正しく処理する必要があります。
Chris Stephens

9

ng-sanitizeを使用すると、htmlにng-clickを追加できないことがわかりました。

これを解決するために、ディレクティブを追加しました。このような:

app.directive('htmldiv', function($compile, $parse) {
return {
  restrict: 'E',
  link: function(scope, element, attr) {
    scope.$watch(attr.content, function() {
      element.html($parse(attr.content)(scope));
      $compile(element.contents())(scope);
    }, true);
  }
}
});

そして、これはHTMLです。

<htmldiv content="theContent"></htmldiv>

幸運を。


6

angular(v1.4)ドキュメントに従ってngBindHtmlを使用してこれをやっただけです、

<div ng-bind-html="expression"></div> 
and expression can be "<ul><li>render me please</li></ul>"

モジュールの依存関係にngSanitizeが含まれていることを確認してください。その後、正常に動作するはずです。


4

スコープ付き属性を使用することを除いて、blrbrと非常によく似た別のソリューションは次のとおりです。

angular.module('app')
.directive('renderHtml', ['$compile', function ($compile) {
    return {
      restrict: 'E',
      scope: {
        html: '='
      },
      link: function postLink(scope, element, attrs) {

          function appendHtml() {
              if(scope.html) {
                  var newElement = angular.element(scope.html);
                  $compile(newElement)(scope);
                  element.append(newElement);
              }
          }

          scope.$watch(function() { return scope.html }, appendHtml);
      }
    };
  }]);

その後

<render-html html="htmlAsString"></render-html>

あなたは置き換えることに注意してくださいelement.append()element.replaceWith()


3

角度で新しい属性またはディレクティブを作成することを使用して、この問題のもう1つの解決策があります

product-specs.html

 <h4>Specs</h4>
        <ul class="list-unstyled">
          <li>
            <strong>Shine</strong>
            : {{product.shine}}</li>
          <li>
            <strong>Faces</strong>
            : {{product.faces}}</li>
          <li>
            <strong>Rarity</strong>
            : {{product.rarity}}</li>
          <li>
            <strong>Color</strong>
            : {{product.color}}</li>
        </ul>

app.js

 (function() {
var app = angular.module('gemStore', []);    
app.directive("     <div ng-show="tab.isSet(2)" product-specs>", function() {
return {
  restrict: 'E',
  templateUrl: "product-specs.html"
};
});

index.html

 <div>
 <product-specs>  </product-specs>//it will load product-specs.html file here.
 </div>

または

<div  product-specs>//it will add product-specs.html file 

または

<div ng-include="product-description.html"></div>

https://docs.angularjs.org/guide/directive


3

ng-includeを使用することもできます

<div class="col-sm-9 TabContent_container" ng-include="template/custom.html">
</div>

「ng-show」を使用して、このテンプレートデータを非表示にできます。


これがng-includeを使用するために必要なすべてのことだと確信していますか?
あざけり2014年

はい..私はそれを試しました。テンプレートを使用している場合は、次のように使用します-<script type = "text / ng-template" id = "custom.html">
Vikash Sharma

2

ここに解決策があります

.filter('trusted',
   function($sce) {
     return function(ss) {
       return $sce.trustAsHtml(ss)
     };
   }
)

これをフィルターとしてng-bind-htmlに適用します

<div ng-bind-html="code | trusted">

ルーベン・デクロップに感謝します


1

使用する

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

そして

angular.module('MyApp', ['ngSanitize']);

そのためにはangular-sanitize.js、例えばhtmlファイルにを含める必要があります

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular-sanitize.js"></script>

0

以下bind-as-htmlは、必要のない単純な(安全でない)ディレクティブですngSanitize

myModule.directive('bindAsHtml', function () {
    return {
        link: function (scope, element, attributes) {
            element.html(scope.$eval(attributes.bindAsHtml));
        }
    };
});

信頼できないコンテンツをバインドすると、セキュリティの問題が発生することに注意してください。

そのように使用してください:

<div bind-as-html="someHtmlInScope"></div>

-1

Angular 4のテンプレートでhtmlを表示するためのパイプの使用例

1.クレートされたパイプescape-html.pipe.ts

`

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
@Pipe({name : 'keepHtml', pure : false})
export class EscapeHtmlPipe implements PipeTransform{
 constructor(private sanitizer : DomSanitizer){
 }
 transform(content){
  return this.sanitizer.bypassSecurityTrustHtml(content);
 }
}

`2.パイプをapp.module.tsに登録する

 import {EscapeHtmlPipe} from './components/pipes/escape-html.pipe';
    declarations: [...,EscapeHtmlPipe]
  1. テンプレートで使用する

        <div class="demoPipe"  [innerHtml]="getDivHtml(obj.header) | keepHtml">

  2. getDivHtml() { //can return html as per requirement}

    関連するcomponent.tsファイルにgetDivHtmlの適切な実装を追加してください。


1
新しいバージョンではなく、AngularJSを使用していると思います。
ハンセン病

-1

[innerHTML]以下のような単純な使用:

<div [innerHTML]="htmlString"></div>

使用する前にng-bind-html...


これは、Angular(Angularバージョン2+)内でのみ使用でき、AngularJS(Angularバージョン1)では使用できません。
ste2425

-1

Angular 7 + ionic 4では、HTMLコンテンツは「[innerHTML]」を使用して表示できます。

<div [innerHTML]="htmlContent"></div>

これもお役に立てば幸いです。ありがとう。


この投稿に反対票を投じる原因となっているこのコードのどこが悪いのか教えてください。このコードを2つのアプリケーションでテストしました。できます。あなたの経験を共有してください。どうもありがとう。
Kamlesh

1
AngularJSはAngular 1.xと同じです。角度7が完全に異なるフレームワークである
Awのスナップ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.