Wie verwenden Sie $ sce.trustAsHtml (Zeichenfolge), um ng-bind-html-unsicher in Angular 1.2+ zu replizieren?


226

ng-bind-html-unsafe wurde in Angular 1.2 entfernt

Ich versuche, etwas dort zu implementieren, wo ich es verwenden muss ng-bind-html-unsafe. In den Dokumenten und auf dem Github Commit heißt es:

ng-bind-html bietet ng-html-bind-unsicheres Verhalten (innerHTML ist das Ergebnis ohne Bereinigung), wenn es an das Ergebnis von $ sce.trustAsHtml (Zeichenfolge) gebunden ist.

Wie machst Du das?


Antworten:


245

Das sollte sein:

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

Plus in Ihrem Controller:

$scope.html = '<ul><li>render me please</li></ul>';
$scope.trustedHtml = $sce.trustAsHtml($scope.html);

anstelle der alten Syntax, bei der Sie die $scope.htmlVariable direkt referenzieren können:

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

Wie mehrere Kommentatoren betonten, $scemuss in den Controller injiziert werden, sonst wird ein $sce undefinedFehler angezeigt.

 var myApp = angular.module('myApp',[]);

 myApp.controller('MyController', ['$sce', function($sce) {
    // ... [your code]
 }]);

10
Wie können Sie dies mit einem von einer Funktion zurückgegebenen Wert tun? <p ng-bind-html = ""> {{description (category.id)}} </ p>
dasper

2
Ich bin mir nicht sicher, ob ich dich richtig verstanden habe, aber: <p ng-bind-html="trustedHtml"></p> und$scope.trustedHtml = $sce.trustAsHtml(description(category.id));
Nenad

1
Ich liebe dich für die Antwort! Anscheinend war das Problem, dass ich 1.0.8 verwendete. Ich habe ein Formular mit einer dynamischen Anzahl von Abschnitten, daher wollte ich bei Änderungen die richtige Beschreibung anzeigen. <p ng-bind-html="description(category.id)"></p>dann die letzte Zeile der Funktion:return $sce.trustAsHtml(value);
Dasper

2
Aber ... var x = sce.trustAsHtml ('foo'); var y = sce.trustAsHtml ('foo'); x == y; false ... Sollte dies nicht eine Endlos-Digest-Schleife erzeugen, da Ihre Funktion ein neues Objekt zurückgibt?
Rych

25
Erwähnenswert ist auch, dass $ sce an den Controller übergeben werden muss oder dass $ sce nicht definiert ist
isimmons

633

Filter

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

Verwendung

<ANY ng-bind-html="value | unsafe"></ANY>

1
Warum brauchst du ngSanitizehier?

2
@OliverJosephAsh, da der Dienst $ sce in ngSanitize definiert ist. Sie haben wichtige Funktionen auseinandergebrochen, sodass wir Angular nur ein wenig verwenden können und nicht immer das gesamte Framework verwenden müssen.
Chris Sattinger

1
Ich habe mich gefragt, welche Auswirkungen dies auf die Sicherheit haben könnte. Ich habe in einer separaten Frage um weitere Klarstellung gebeten . Alle Beiträge geschätzt!
Philip Bulley

9
@felix in Version 1.2 (als sie dies hinzufügten) ist es standardmäßig als Teil des Kerns aktiviert, nicht ngSanitize, so dass es nicht nötig istngSanitize
TheSharpieOne

2
Dies ist eine Entwurfsentscheidung des Winkelteams - so sollten Filter implementiert werden - wenn Sie es anders machen, funktionieren sie nicht. Der Grund, warum dies eine Funktion zurückgeben muss, ist, dass der Winkel die Verarbeitung verzögern kann, bis er den richtigen Moment findet. Andernfalls hätte das Framework keinen Einfluss darauf, wann der Filter aufgerufen wird. Das ist sowohl gut als auch schlecht, aber soweit ich das beurteilen kann, ist es notwendig, mit der schwierigen Verarbeitung von Angulars fertig zu werden. Weitere Informationen hier: docs.angularjs.org/api/ng/provider/$filterProvider
Chris

16

Persönlich bereinige ich alle meine Daten mit einigen PHP-Bibliotheken, bevor ich in die Datenbank gehe, sodass für mich kein weiterer XSS-Filter erforderlich ist.

Aus AngularJS 1.0.8

directives.directive('ngBindHtmlUnsafe', [function() {
    return function(scope, element, attr) {
        element.addClass('ng-binding').data('$binding', attr.ngBindHtmlUnsafe);
        scope.$watch(attr.ngBindHtmlUnsafe, function ngBindHtmlUnsafeWatchAction(value) {
            element.html(value || '');
        });
    }
}]);

Benutzen:

<div ng-bind-html-unsafe="group.description"></div>

So deaktivieren Sie $sce:

app.config(['$sceProvider', function($sceProvider) {
    $sceProvider.enabled(false);
}]);

Mir ist unklar, was der Unterschied zwischen den beiden Beispielen ist. Eines unserer Teammitglieder hat ein Problem mit System.out.println (& ldquo; Hallo Welt! & Rdquo;); in der Datenbank. Sie verwendet <div data-ng-bind-html = "text"> </ div> und es erscheint auf der Seite als: System.out.println (& ldquo; Hello World! & Rdquo;);. Wollen Sie damit sagen, dass die Verwendung Ihrer ngBindHtmlUnsafe-Direktive dieses Problem beheben würde?
Alan2

@ Alan Ich glaube, es würde funktionieren, wenn es so wäre. Ich habe es <script>System.out.printIn("Hello World!");</script>nicht persönlich versucht, weil mein PHP alle JS aus den Benutzereingaben entfernt hat. Ich habe mein zweites Beispiel entfernt, weil Angulars native in jeder Hinsicht überlegen ist. Verwenden Sie einfach dieses.
Michael J. Calkins

Wie dies für den Summernote-Editor gemacht wird, zunächst erhalte ich die JSON-Daten (die HTML enthalten) vom Server, in Summernote verwende ich das ng-Modell. wie man den Code als vertrauenswürdig macht, um im Summernote-Editor
angezeigt zu werden

8

var line = "<label onclick="alert(1)">aaa</label>";

1. Filter verwenden

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

using (html):

<span ng-bind-html="line | unsafe"></span>
==>click `aaa` show alert box

2. Verwenden Sie ngSanitize: sicherer

einschließen angular-sanitize.js

<script src="bower_components/angular-sanitize/angular-sanitize.js"></script>

ngSanitizein der Wurzelwinkel-App hinzufügen

var app = angular.module("app", ["ngSanitize"]);

using (html):

<span ng-bind-html="line"></span>
==>click `aaa` nothing happen

Wie dies für den Summernote-Editor gemacht wird, zunächst erhalte ich die JSON-Daten (die HTML enthalten) vom Server, in Summernote verwende ich das ng-Modell. wie man den Code als vertrauenswürdig macht, um im Summernote-Editor
angezeigt zu werden

7

Das einfache Erstellen eines Filters reicht aus. (Beantwortet für Angular 1.6)

.filter('trustHtml', [
        '$sce',
        function($sce) {
            return function(value) {
                return $sce.trustAs('html', value);
            }
        }
    ]);

Und verwenden Sie dies wie folgt im HTML.

<h2 ng-bind-html="someScopeValue | trustHtml"></h2>

Dieser behebt den Fehler mit uglifying: "Unbekannter Anbieter: eProvider <- e <- unsafeFilter"
Valera Tumash

3

Wenn Sie die alte Direktive zurückhaben möchten, können Sie diese zu Ihrer App hinzufügen:

Richtlinie:

directives.directive('ngBindHtmlUnsafe', ['$sce', function($sce){
    return {
        scope: {
            ngBindHtmlUnsafe: '=',
        },
        template: "<div ng-bind-html='trustedHtml'></div>",
        link: function($scope, iElm, iAttrs, controller) {
            $scope.updateView = function() {
                $scope.trustedHtml = $sce.trustAsHtml($scope.ngBindHtmlUnsafe);
            }

            $scope.$watch('ngBindHtmlUnsafe', function(newVal, oldVal) {
                $scope.updateView(newVal);
            });
        }
    };
}]);

Verwendung

<div ng-bind-html-unsafe="group.description"></div>

Quelle - https://github.com/angular-ui/bootstrap/issues/813


Benimmt sich nicht gleich.
Casey

Wie dies für den Summernote-Editor gemacht wird, zunächst erhalte ich die JSON-Daten (die HTML enthalten) vom Server, in Summernote verwende ich das ng-Modell. wie man den Code als vertrauenswürdig macht, um im Summernote-Editor
angezeigt zu werden

3

JavaScript

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

HTML

<pre ng-bind-html="get_pre(html)"></pre>

Wie dies für den Summernote-Editor gemacht wird, zunächst erhalte ich die JSON-Daten (die HTML enthalten) vom Server, in Summernote verwende ich das ng-Modell. wie man den Code als vertrauenswürdig macht, um im Summernote-Editor
angezeigt zu werden

1

Wenn Sie für Rails (zumindest in meinem Fall) den Edelstein Angularjs-Rails verwenden , denken Sie bitte daran, das Desinfektionsmodul hinzuzufügen

//= require angular
//= require angular-sanitize

Und dann laden Sie es in Ihre App ...

var myDummyApp = angular.module('myDummyApp', ['ngSanitize']);

Dann können Sie Folgendes tun:

Auf der Vorlage:

%span{"ng-bind-html"=>"phone_with_break(x)"}

Und schließlich:

$scope.phone_with_break = function (x) {
  if (x.phone != "") {
   return x.phone + "<br>";
  }
  return '';
}

Wie dies für den Summernote-Editor gemacht wird, zunächst erhalte ich die JSON-Daten (die HTML enthalten) vom Server, in Summernote verwende ich das ng-Modell. wie man den Code als vertrauenswürdig macht, um im Summernote-Editor
angezeigt zu werden


0
my helpful code for others(just one aspx to do text area post)::

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication45.WebForm1" %>

<!DOCTYPE html>

    enter code here

<html ng-app="htmldoc" xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="angular.min.js"></script>
    <script src="angular-sanitize.min.js"></script>
    <script>
        angular.module('htmldoc', ['ngSanitize']).controller('x', function ($scope, $sce) {
            //$scope.htmlContent = '<script> (function () { location = \"http://moneycontrol.com\"; } )()<\/script> In last valid content';
            $scope.htmlContent = '';
            $scope.withoutSanitize = function () {
                return $sce.getTrustedHtml($scope.htmlContent);
            };
            $scope.postMessage = function () {
                var ValidContent = $sce.trustAsHtml($scope.htmlContent);

                //your ajax call here
            };
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
        Example to show posting valid content to server with two way binding
        <div ng-controller="x">
            <p ng-bind-html="htmlContent"></p>
            <textarea ng-model="htmlContent" ng-trim="false"></textarea>
            <button ng-click="postMessage()">Send</button>
        </div>
    </form>
</body>
</html>

0
$scope.trustAsHtml=function(scope)
{
    return $sce.trustAsHtml(scope);
}
<p class="card-text w-100" ng-bind-html="trustAsHtml(note.redoq_csd_product_lead_note)"></p>

3
Bitte posten Sie nicht nur Code als Antwort, sondern geben Sie auch eine Erklärung an, was Ihr Code tut und wie er das Problem der Frage löst. Antworten mit einer Erklärung sind im Allgemeinen von höherer Qualität und ziehen eher positive Stimmen an.
Mark Rotteveel
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.