Fügen Sie HTML vom AngularJS-Controller in die Ansicht ein

800

Ist es möglich, ein HTML- Fragment in einem AngularJS-Controller zu erstellen und dieses HTML in der Ansicht anzuzeigen?

Dies ergibt sich aus der Anforderung, einen inkonsistenten JSON-Blob in eine verschachtelte Liste von id: valuePaaren umzuwandeln. Daher wird der HTML- Code im Controller erstellt und ich möchte ihn jetzt anzeigen.

Ich habe eine Modelleigenschaft erstellt, kann diese jedoch nicht in der Ansicht rendern, ohne nur den HTML- Code zu drucken .


Aktualisieren

Es scheint, dass das Problem durch das eckige Rendern des erstellten HTML-Codes als Zeichenfolge in Anführungszeichen entsteht. Ich werde versuchen, einen Weg zu finden, um dies zu umgehen.

Beispielsteuerung:

var SomeController = function () {

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

Beispielansicht:

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

Gibt:

<div>
    "<ul><li>render me please</li></ul>"
</div>
Swaff
quelle
1
Lesen Sie auch diese Frage und fragen Sie, ob es möglich ist, Skripte in eingefügtem HTML auszuführen.
Enigment
Ist es möglich, mehrere Objekte an dieselbe ng-Bindung zu binden? wie `` `ng-bind =" site.address_1 site.address_2 site.zip "
Fauverismus
Wenn Sie eine Menge Dinge auf Ihrer Seite haben, müssen Sie die Zeile 15046 von angle.js (Wahnsinn) von ändern function htmlSanitizer(html) {.... Angular Devs haben entschieden, dass Sie in der Lage sein sollten, jede HTML-Bindung zu finden, indem Sie langsam alle versteckten Elemente Ihrer Seiten nacheinander durchgehen, um das EINZIGE fehlende Stück HTML zu finden. !!! sehr wütend auf eine solche Annahme !!!
user3338098
Entschuldigung, die von Luke gewählte Antwort ist möglicherweise nicht die völlig richtige. Die richtige Antwort finden Sie in einer anderen Frage hier . Grundsätzlich "ng-bind-html-unsafe rendert den Inhalt nur als HTML. Der Angular-Bereich wird nicht an das resultierende DOM gebunden. Zu diesem Zweck müssen Sie den $ compile-Dienst verwenden."
gm2008
ng-bind entfernt alle internen HTML-Dateien. Das ist nicht, wie Filter funktionieren würde, es ist in Ordnung, wenn Filter der einzige Wert ist
Muhammad Umer

Antworten:

1120

Verwenden Sie für Angular 1.x ng-bind-htmlim HTML:

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

Zu diesem Zeitpunkt wird eine attempting to use an unsafe value in a safe contextFehlermeldung angezeigt , sodass Sie entweder ngSanitize oder $ sce verwenden müssen , um dies zu beheben.

$ sce

Verwenden Sie $sce.trustAsHtml()im Controller, um die HTML-Zeichenfolge zu konvertieren.

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

ngSanitize

Es gibt 2 Schritte:

  1. Fügen Sie die Ressource angle-sanitize.min.js hinzu, dh:
    <script src="lib/angular/angular-sanitize.min.js"></script>

  2. Fügen Sie in eine js-Datei (Controller oder normalerweise app.js) ngSanitize ein, dh:
    angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngSanitize'])

Luke Madera
quelle
30
In Angular 1.2 ng-bind-html-unsafewurde entfernt und die beiden Direktiven wurden kombiniert. Siehe: github.com/angular/angular.js/blob/master/…
Sasha Chedygov
60
Ohne ngSanitize kann dies jetzt mit verwendet werden $sce. Injizieren Sie es in den Controller und leiten Sie das HTML durch. $scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml(someHtmlVar);Ansonsten bekam ich immer wiederattempting to use an unsafe value in a safe context
Matsemann
3
Wir müssen hier ein bisschen aufräumen, was der richtige Weg ist, nichts scheint für mich zu funktionieren.
landete am
9
stackoverflow.com/questions/21829275/… <- hat bei mir funktioniert :) Keine der Optionen in den Antworten hier hat leider funktioniert
anpatel
7
Damit die Leute nicht entmutigt sind, funktioniert das neueste Update dieser Antwort in Verbindung mit der ngSanitize-Anforderung am Ende der Antwort tatsächlich.
Ben Cull
312

Sie können auch einen Filter wie folgt erstellen:

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

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

Dann in der Ansicht

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

Hinweis : Dieser Filter vertraut allen an ihn übergebenen HTML-Dateien und kann eine XSS-Sicherheitsanfälligkeit darstellen, wenn Variablen mit Benutzereingaben an ihn übergeben werden.

Katie Astrauskas
quelle
@ Katie Astrauskas, danke für die Antwort! Sehr sauberer Weg. BTW ngResourceAbhängigkeit ist nicht neccesary.
Athlan
28
Verwenden Sie diese Option nur, wenn Sie dem HTML-Code vollständig vertrauen. Dadurch wird der HTML-Code in keiner Weise bereinigt, sondern Angular kann ihn nur in die Seite einfügen. Schädliches HTML kann XSS-Angriffe provozieren.
Jan.vdbergh
Wenn die Leistung wichtig ist, sollten Sie die Verwendung von Filtern vermeiden. Ein Filter löst jedes Mal zwei Digests aus.
Tantelope
14
Warum heißt der Filter sanitize? Dies ist so irreführend, dass es eigentlich nichts desinfiziert. Stattdessen sollte es aufgerufen trustwerden trustSafeoder etwas Ähnliches.
Denis Pshenov
1
Wunderbare Antwort. rawHtmlist mein Name für den Filter anstelle von sanitize.
Wumms
119

Angular JS zeigt HTML innerhalb des Tags an

Die im obigen Link bereitgestellte Lösung hat bei mir funktioniert, keine der Optionen in diesem Thread hat funktioniert. Für alle, die mit AngularJS Version 1.2.9 dasselbe suchen

Hier ist eine Kopie:

Ok, ich habe eine Lösung dafür gefunden:

JS:

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

HTML:

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

BEARBEITEN:

Hier ist das Setup:

JS-Datei:

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-Datei:

<div ng-controller="MyController">
    <div ng-bind-html="renderHtml(body)"></div>
</div>
anpatel
quelle
7
Beachten Sie, dass Sie unbedingt sicher sein müssen, dass dem HTML-Code vertraut werden kann. Andernfalls steht die Tür für XSS-Angriffe weit offen.
jan.vdbergh
Diese Lösung, die eine Funktion zum Rendern des HTML-Codes verwendet, ist die einzige, die für mich funktioniert hat.
MarceloBarbosa
Wofür ist das '$ http'?
Soldeplata Saketos
@SoldeplataSaketos nichts Besonderes, ich glaube, ich habe es zu der Zeit lokal versucht und am Ende die Abhängigkeit kopiert.
Anpatel
Gleiche Antwort Update hier. stackoverflow.com/questions/21829275/…
Surya R Praveen
65

Glücklicherweise benötigen Sie keine ausgefallenen Filter oder unsicheren Methoden, um diese Fehlermeldung zu vermeiden. Dies ist die vollständige Implementierung, um HTML-Markups in einer Ansicht auf die beabsichtigte und sichere Weise ordnungsgemäß auszugeben.

Das Desinfektionsmodul muss nach Angular enthalten sein:

<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>

Dann muss das Modul geladen werden:

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

Auf diese Weise können Sie Markups in eine Zeichenfolge eines Controllers, einer Direktive usw. einfügen:

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

Schließlich muss es in einer Vorlage wie folgt ausgegeben werden:

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

Was die erwartete Ausgabe erzeugt: 42 ist die Antwort .

Pier-Luc Gendreau
quelle
1
Versuchen Sie etwas HTML wie <div><label>Why My Input Element Missing</label><input /></div>... Wenn es Sie überrascht, dann aktualisieren Sie Ihre Antwort plz .. Weil ich alle 10 + Vote-Lösungen getestet habe .. Ihre Lösung hat bei mir nicht funktioniert, um meine Eingabe-Tags zu sehen .. gut, sonst .. Ich hatte Verwendung$sce.trustAsHtml(html)
Sami
Diese Lösung funktioniert, möchten Sie eine jsfiddle oder plunkr posten?
Pier-Luc Gendreau
Dies sollte wirklich die Antwort sein, wenn Sie den neuesten Winkel verwenden
Sandeep
61

Ich habe es heute versucht, der einzige Weg, den ich gefunden habe, war dieser

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

Damax
quelle
6
Diese Lösung sollte nur verwendet werden, wenn die Quelle vertrauenswürdig ist, um Cross-Site-Scripting-Angriffe zu vermeiden.
Bertrand
3
Ab Angular 1.0.2 funktioniert dies für mich, ohne dass andere Dateien oder Verbindungen erforderlich sind.
Enigment
1
Mit Angular 1.0.8 hat das bei mir funktioniert. Beachten Sie jedoch die Warnung von @ Bertrand. Vertrauen Sie der Quelle.
Jack Slingerland
12
Zum späteren Nachschlagen wurde ng-bind-html-unsafe in Version 1.2 entfernt. Jetzt benötigen Sie das ngSanitize-Modul. Um unsicheren HTML-Code zu binden, sollten Sie die Methode $ sce.trustAsHtml verwenden.
Lucas Lazaro
53

ng-bind-html-unsafe funktioniert nicht mehr.

Dies ist der kürzeste Weg:

Erstellen Sie einen Filter:

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

Und aus Ihrer Sicht:

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

PS Bei dieser Methode müssen Sie das ngSanitizeModul nicht einschließen .

Bidhan Bhattarai
quelle
3
Dies ist die beste Lösung, die ich hier für Angular 1.2 gesehen habe. Die $scein der akzeptierten Antwort verwendete Lösung hat bei mir nicht funktioniert und ich wollte keine zusätzliche Abhängigkeit für etwas so Triviales aufnehmen.
Daniel Bonnell
Die Lösung von Bidhan Bhattarai hat für mich funktioniert. Angular 1.6.1
Mediaguru
25

auf HTML

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

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

ODER

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

am Controller

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

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

funktioniert auch mit $scope.comment.msg = $sce.trustAsHtml(html);

Sotos
quelle
1
$sceist ordentlich, aber konnte ein Benutzer hier nicht einfach einen Haltepunkt hinzufügen und schädlichen Code this.myCtrl.comment.msgmithilfe eines Debuggers wiederherstellen ?
BradGreens
andererseits BradGreens, könnten Sie dasselbe auch mit ng-bind-html-unsicher tun?
CodeOverRide
4
Wenn jemand seinen eigenen Browser hacken will, kann er, wen interessiert das? Andere Benutzer sind davon nicht betroffen. @BradGreens Ist das die Frage?
Chris Stephens
@ ChrisStephens du bist richtig. Ich denke, das beantwortet meine Frage, aber meiner Meinung nach sind diese Funktionen der wahrgenommenen Sicherheit näher als der tatsächlichen Sicherheit. Vielleicht schützt es vor automatisierten Angriffen? Ich habe nie klar verstanden, warum dies der App wirklich hilft. Meine App muss JEDER Instanz zum Rendern von wysiwyg-HTML einen Filter hinzufügen, da sie Inline-CSS enthalten kann, das entfernt ng-bind-htmlwird.
BradGreens
1
Nun, diese Funktionen helfen bei der Reduzierung sicherer Codierungsfehler. Insbesondere das Problem mit Markup / Code-Injection. Standardmäßig werden alle gebundenen Daten zur Anzeige codiert. Wenn Sie also Markup ausgeben möchten, müssen Sie überlegen, was Sie tun möchten. Ohne diese Funktionen können Sie viel allein mit der serverseitigen Sicherheit tun. Um jedoch Bedenken auszuräumen, sollte die Client-App dafür verantwortlich sein, dass die Daten für die Anzeige korrekt verarbeitet werden.
Chris Stephens
9

Ich habe festgestellt, dass ich mit ng-sanitize kein ng-click im HTML hinzufügen konnte.

Um dies zu lösen, habe ich eine Richtlinie hinzugefügt. So was:

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);
  }
}
});

Und das ist der HTML:

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

Viel Glück.

Matt
quelle
6

Haben Sie dies einfach mit ngBindHtml getan, indem Sie eckigen (v1.4) Dokumenten gefolgt sind.

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

Stellen Sie sicher, dass Sie ngSanitize in die Abhängigkeiten des Moduls aufnehmen. Dann sollte es gut funktionieren.

Henry Neo
quelle
4

Eine andere Lösung, die blrbr sehr ähnlich ist, außer dass ein Attribut mit Gültigkeitsbereich verwendet wird, ist:

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);
      }
    };
  }]);

Und dann

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

Hinweis : Sie ersetzen können element.append()mitelement.replaceWith()

abbaf33f
quelle
3

Es gibt eine weitere Lösung für dieses Problem, indem neue Attribute oder Anweisungen im Winkel erstellt werden.

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>

oder

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

oder

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

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

Yugi
quelle
3

Sie können auch ng-include verwenden .

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

Sie können "ng-show" verwenden , um diese Vorlagendaten auszublenden.

Vikash Sharma
quelle
Sind Sie sicher, dass dies alles ist, was Sie tun müssen, um ng-include zu verwenden?
Fauverismus
ja .. ich habe es ausprobiert. und wenn Sie eine Vorlage verwenden, verwenden Sie sie folgendermaßen: <script type = "text / ng-template" id = "custom.html">
Vikash Sharma
2

Hier ist die Lösung, einen Filter wie diesen zu machen

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

und wende dies als Filter auf das ng-bind-html like an

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

und danke an Ruben Decrop

Bahri Noredine
quelle
1

Verwenden

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

und

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

Dazu müssen Sie angular-sanitize.jsbeispielsweise in Ihre HTML-Datei mit aufnehmen

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

Hier ist eine einfache (und unsichere) bind-as-htmlAnweisung, ohne dass Folgendes erforderlich ist ngSanitize:

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

Beachten Sie, dass dies zu Sicherheitsproblemen führen kann, wenn nicht vertrauenswürdige Inhalte gebunden werden.

Verwenden Sie wie folgt:

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

quelle
-1

Arbeitsbeispiel mit Pipe zur Anzeige von HTML in einer Vorlage mit Angular 4.

1.Crated Pipe 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. Registrieren Sie die Pipe in app.module.ts

 import {EscapeHtmlPipe} from './components/pipes/escape-html.pipe';
    declarations: [...,EscapeHtmlPipe]
  1. Verwenden Sie in Ihrer Vorlage

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

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

    Bitte fügen Sie die entsprechende Implementierung für getDivHtml in die zugehörige Datei component.ts ein.

Sagar Misal
quelle
1
Ich denke, er arbeitet mit AngularJS, nicht mit der neueren Version.
Lepra
-1

Nur einfache Verwendung [innerHTML], wie unten:

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

Bevor Sie verwenden mussten ng-bind-html...

Alireza
quelle
Dies ist nur in Angular (Angular Version 2+) verfügbar, nicht in AngularJS (Angular Version 1).
ste2425
-1

In Angular 7 + ionic 4 kann der HTML-Inhalt mithilfe von "[innerHTML]" angezeigt werden:

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

Ich hoffe, das wird dir auch helfen. Vielen Dank.

Kamlesh
quelle
Bitte sagen Sie mir, was in diesem Code falsch ist, was dazu führt, dass dieser Beitrag abgelehnt wird. Ich habe diesen Code in meiner 2-Anwendung getestet. Es klappt. Bitte teilen Sie Ihre Erfahrungen. Vielen Dank.
Kamlesh
1
AngularJS entspricht Angular 1.x. Angular 7 ist ein völlig anderes Framework
Aw Snap