Comment utilisez-vous $ sce.trustAsHtml (chaîne) pour répliquer ng-bind-html-unsafe dans Angular 1.2+

226

ng-bind-html-unsafe a été supprimé dans Angular 1.2

J'essaie d'implémenter quelque chose où je dois utiliser ng-bind-html-unsafe. Dans les documents et sur le github, ils disent:

ng-bind-html fournit un comportement similaire à ng-html-bind-unsafe (innerHTML est le résultat sans nettoyage) lorsqu'il est lié au résultat de $ sce.trustAsHtml (chaîne).

Comment est-ce que tu fais ça?

timhaak
la source

Réponses:

245

Ça devrait être:

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

plus dans votre contrôleur:

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

au lieu de l'ancienne syntaxe, où vous pouviez référencer $scope.htmldirectement une variable:

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

Comme plusieurs commentateurs l'ont souligné, $scedoit être injecté dans le contrôleur, sinon vous obtiendrez une $sce undefinederreur.

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

 myApp.controller('MyController', ['$sce', function($sce) {
    // ... [your code]
 }]);
Nenad
la source
10
Comment pouvez-vous faire cela avec une valeur renvoyée par une fonction? <p ng-bind-html = ""> {{description (category.id)}} </p>
dasper
2
Je ne sais pas si je vous ai bien compris, mais: <p ng-bind-html="trustedHtml"></p> et$scope.trustedHtml = $sce.trustAsHtml(description(category.id));
Nenad
1
Je t'aime pour avoir répondu! Apparemment, le problème était que j'utilisais 1.0.8. J'ai un formulaire avec un nombre dynamique de sections, ainsi de suite, je voulais montrer la bonne description. <p ng-bind-html="description(category.id)"></p>puis la dernière ligne de la fonction:return $sce.trustAsHtml(value);
dasper
2
Mais ... var x = sce.trustAsHtml ('foo'); var y = sce.trustAsHtml ('foo'); x == y; false ... Cela ne devrait-il donc pas créer une boucle de résumé infinie puisque votre fonction retourne un nouvel objet?
rych
25
Il convient également de mentionner que $ sce doit être passé dans le contrôleur ou que vous obtenez $ sce n'est pas défini
isimmons
634

Filtre

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

Usage

<ANY ng-bind-html="value | unsafe"></ANY>
Chris
la source
1
Pourquoi avez-vous besoin ngSanitizeici?
2
@OliverJosephAsh car le service $ sce est défini dans ngSanitize. ils ont séparé les principales fonctionnalités afin que nous puissions utiliser un peu angulaire et ne pas toujours avoir à utiliser l'intégralité du cadre.
Chris Sattinger
1
Je me demandais quelles pourraient être les implications pour la sécurité de quelque chose comme ça? J'ai demandé plus de précisions dans une question distincte . Toutes les contributions sont appréciées!
Philip Bulley
9
@felix dans la version 1.2 (quand ils l'ont ajouté), il est activé par défaut dans le cadre du noyau, non ngSanitize, donc il n'y a pas besoin dengSanitize
TheSharpieOne
2
Il s'agit d'une décision de conception prise par l'équipe angulaire - c'est ainsi que les filtres doivent être implémentés - si vous le faites autrement, ils ne fonctionneront pas. La raison pour laquelle cela doit retourner une fonction est que l'angulaire peut retarder le traitement jusqu'à ce qu'il «trouve le bon moment». Sinon, le framework n'aurait aucune influence sur l'appel du filtre. C'est à la fois bon et mauvais, mais pour autant que je sache - il est nécessaire de faire face au traitement délicat des angulaires. Plus d'informations ici: docs.angularjs.org/api/ng/provider/$filterProvider
Chris
16

Personnellement, je désinfecte toutes mes données avec certaines bibliothèques PHP avant d'entrer dans la base de données, il n'y a donc pas besoin d'un autre filtre XSS pour moi.

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

Utiliser:

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

Pour désactiver $sce:

app.config(['$sceProvider', function($sceProvider) {
    $sceProvider.enabled(false);
}]);
Michael J. Calkins
la source
Je ne sais pas quelle est la différence entre les deux exemples. Un des membres de notre équipe a un problème où il a System.out.println (& ldquo; Hello World! & Rdquo;); dans la base de données. Elle utilise <div data-ng-bind-html = "text"> </div> et il apparaît sur la page sous la forme: System.out.println (& ldquo; Hello World! & Rdquo;) ;. Êtes-vous en train de dire que l'utilisation de votre directive ngBindHtmlUnsafe résoudrait ce problème?
Alan2
@Alan Je crois que cela fonctionnerait si c'était le cas <script>System.out.printIn("Hello World!");</script>, je n'ai pas essayé personnellement parce que mon PHP a supprimé tous les JS des entrées utilisateur. J'ai supprimé mon deuxième exemple parce que celui natif d'Angular est supérieur à tous égards, utilisez-le simplement.
Michael J.Calkins
Comment faire cela pour l'éditeur Summernote, au départ, j'obtiendrai les données JSON (qui contiennent du HTML) du serveur, dans Summernote, j'utilise ng-model. comment rendre le code aussi fiable à afficher dans l'éditeur de
sommation
8

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

1. utiliser un filtre

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

en utilisant (html):

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

2. utilisez ngSanitize: plus sûr

comprendre angular-sanitize.js

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

ajouter ngSanitizeune application angulaire racine

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

en utilisant (html):

<span ng-bind-html="line"></span>
==>click `aaa` nothing happen
nguyên
la source
Comment faire cela pour l'éditeur Summernote, au départ, j'obtiendrai les données JSON (qui contiennent du HTML) du serveur, dans Summernote, j'utilise ng-model. comment rendre le code aussi fiable à afficher dans l'éditeur de
sommation
7

La simple création d'un filtre fera l'affaire. (Répondu pour Angular 1.6)

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

Et utilisez-le comme suit dans le html.

<h2 ng-bind-html="someScopeValue | trustHtml"></h2>
ACIER
la source
Celui-ci corrige l'erreur en uglifiant: "Fournisseur inconnu: eProvider <- e <- unsafeFilter"
Valera Tumash
3

Si vous souhaitez récupérer l'ancienne directive, vous pouvez l'ajouter à votre application:

Directif:

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

Usage

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

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

Adrian Enriquez
la source
Ne se comporte pas de la même façon.
Casey
Comment faire cela pour l'éditeur Summernote, au départ, j'obtiendrai les données JSON (qui contiennent du HTML) du serveur, dans Summernote, j'utilise ng-model. comment rendre le code de confiance pour l'afficher dans l'éditeur de
sommation
3

Javascript

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

HTML

<pre ng-bind-html="get_pre(html)"></pre>
wcc526
la source
Comment faire cela pour l'éditeur Summernote, au départ, j'obtiendrai les données JSON (qui contiennent du HTML) du serveur, dans Summernote, j'utilise ng-model. comment rendre le code aussi fiable à afficher dans l'éditeur de
sommation
1

Pour Rails (au moins dans mon cas) si vous utilisez le joyau angularjs-rails , n'oubliez pas d'ajouter le module sanitize

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

Et puis chargez-le dans votre application ...

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

Ensuite, vous pouvez effectuer les opérations suivantes:

Sur le modèle:

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

Et éventuellement:

$scope.phone_with_break = function (x) {
  if (x.phone != "") {
   return x.phone + "<br>";
  }
  return '';
}
SomeDudeSomewhere
la source
Comment faire cela pour l'éditeur Summernote, au départ, j'obtiendrai les données JSON (qui contiennent du HTML) du serveur, dans Summernote, j'utilise ng-model. comment rendre le code de confiance pour l'afficher dans l'éditeur de
sommation
Découvrez ceci: github.com/summernote/summernote/issues/…
SomeDudeSomewhere
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>
Saurabh
la source
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>
Surya Pratim Mukherjee
la source
3
Veuillez ne pas publier uniquement le code comme réponse, mais inclure également une explication de ce que fait votre code et comment il résout le problème de la question. Les réponses accompagnées d'une explication sont généralement de meilleure qualité et sont plus susceptibles d'attirer des votes positifs.
Mark Rotteveel