¿Cómo se usa $ sce.trustAsHtml (string) para replicar ng-bind-html-inseguro en Angular 1.2+

226

ng-bind-html-unsafe fue eliminado en Angular 1.2

Estoy tratando de implementar algo donde necesito usar ng-bind-html-unsafe. En los documentos y en el commit de github dicen:

ng-bind-html proporciona un comportamiento similar a ng-html-bind-inseguro (innerHTML es el resultado sin desinfección) cuando está vinculado al resultado de $ sce.trustAsHtml (cadena).

¿Cómo haces esto?

Timhaak
fuente
posible duplicado de Insertar HTML a la vista usando AngularJS
kontur

Respuestas:

245

Eso debería ser:

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

más en su controlador:

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

en lugar de la sintaxis anterior, donde puede hacer referencia a la $scope.htmlvariable directamente:

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

Como señalaron varios comentaristas, $scedebe inyectarse en el controlador; de lo contrario, obtendrá un $sce undefinederror.

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

 myApp.controller('MyController', ['$sce', function($sce) {
    // ... [your code]
 }]);
Nenad
fuente
10
¿Cómo puedes hacer esto con un valor devuelto por una función? <p ng-bind-html = ""> {{description (category.id)}} </p>
fecha
2
No estoy seguro si te entendí bien, pero: <p ng-bind-html="trustedHtml"></p> y$scope.trustedHtml = $sce.trustAsHtml(description(category.id));
Nenad
1
¡Te amo por responder! Aparentemente el problema era yo usando 1.0.8. Tengo un formulario con un número dinámico de secciones, así que al cambiar quería mostrar la descripción adecuada. <p ng-bind-html="description(category.id)"></p>entonces la última línea de la función:return $sce.trustAsHtml(value);
dasper
2
Pero ... var x = sce.trustAsHtml ('foo'); var y = sce.trustAsHtml ('foo'); x == y; falso ... Entonces, ¿no debería esto crear un ciclo de resumen infinito ya que su función devuelve un nuevo objeto?
rych 01 de
25
También vale la pena mencionar que $ sce debe pasarse al controlador o se obtiene $ sce no está definido
isimmons
634

Filtrar

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

Uso

<ANY ng-bind-html="value | unsafe"></ANY>
Chris
fuente
1
¿Por qué necesitas ngSanitizeaquí?
2
@OliverJosephAsh porque el servicio $ sce está definido en ngSanitize. separaron la funcionalidad principal para que podamos usar angular solo un poco y no siempre tengamos que usar todo el marco.
Chris Sattinger
1
Me he estado preguntando cuáles podrían ser las implicaciones de seguridad de algo como esto. He pedido más aclaraciones en una pregunta separada . Todas las aportaciones apreciadas!
Philip Bulley
99
@felix en la versión 1.2 (cuando agregaron esto) está habilitado por defecto como parte del núcleo, no ngSanitize, por lo que no hay necesidad dengSanitize
TheSharpieOne
2
Esta es una decisión de diseño tomada por el equipo angular; así es como se deben implementar los filtros; si lo hace de otra manera, no funcionarán. La razón por la que esto debe devolver una función es que angular puede retrasar el procesamiento hasta que "encuentre el momento correcto". De lo contrario, el marco no tendría ninguna influencia sobre cuándo se llama al filtro. Eso es bueno y malo, pero por lo que puedo decir, es necesario hacer frente al complicado procesamiento de los angulares. Más información aquí: docs.angularjs.org/api/ng/provider/$filterProvider
Chris
16

Personalmente desinfecta todos mis datos con algunas bibliotecas PHP antes de ingresar a la base de datos, por lo que no necesito otro filtro XSS para mí.

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

Usar:

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

Para deshabilitar $sce:

app.config(['$sceProvider', function($sceProvider) {
    $sceProvider.enabled(false);
}]);
Michael J. Calkins
fuente
No estoy claro cuál es la diferencia entre los dos ejemplos. Uno de los miembros de nuestro equipo tiene un problema cuando tiene System.out.println (& ldquo; Hello World! & Rdquo;); en la base de datos. Ella está usando <div data-ng-bind-html = "text"> </div> y aparece en la página como: System.out.println (& ldquo; Hello World! & Rdquo;) ;. ¿Estás diciendo que usar tu directiva ngBindHtmlUnsafe solucionaría este problema?
Alan2
@ Alan Creo que funcionaría si lo fuera <script>System.out.printIn("Hello World!");</script>, no lo he intentado personalmente porque mi PHP eliminó todo JS de la entrada del usuario. Eliminé mi segundo ejemplo porque el nativo de Angular es superior en todos los sentidos, solo use ese.
Michael J. Calkins el
Cómo hacer esto para el editor de summernote, inicialmente obtendré los datos json (que contienen html) del servidor, en summernote estoy usando ng-model. cómo hacer que el código sea confiable para que se muestre en el editor de
summernote
8

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

1. usar filtro

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

utilizando (html):

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

2. use ngSanitize: más seguro

incluir angular-sanitize.js

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

agregar ngSanitizeen la aplicación angular raíz

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

utilizando (html):

<span ng-bind-html="line"></span>
==>click `aaa` nothing happen
nguyên
fuente
Cómo hacer esto para el editor de summernote, inicialmente obtendré los datos json (que contienen html) del servidor, en summernote estoy usando ng-model. cómo hacer que el código sea confiable para que se muestre en el editor de
summernote
7

Simplemente crear un filtro hará el truco. (Respondido para Angular 1.6)

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

Y use esto como sigue en el html.

<h2 ng-bind-html="someScopeValue | trustHtml"></h2>
ACERO
fuente
Éste corrige el error con uglifying: "Proveedor desconocido: eProvider <- e <- unsafeFilter"
Valera Tumash
3

Si desea recuperar la directiva anterior, puede agregarla a su aplicación:

Directiva:

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

Uso

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

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

Adrián Enríquez
fuente
No se comporta igual.
Casey
Cómo hacer esto para el editor de summernote, inicialmente obtendré los datos json (que contienen html) del servidor, en summernote estoy usando ng-model. cómo hacer que el código como de confianza a la visualización en el editor summernote
codelearner
3

JavaScript

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

HTML

<pre ng-bind-html="get_pre(html)"></pre>
wcc526
fuente
Cómo hacer esto para el editor de summernote, inicialmente obtendré los datos json (que contienen html) del servidor, en summernote estoy usando ng-model. cómo hacer que el código sea confiable para que se muestre en el editor de
summernote
1

Para Rails (al menos en mi caso) si está utilizando la gema angularjs-rails , recuerde agregar el módulo de desinfección

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

Y luego cárgalo en tu aplicación ...

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

Entonces puedes hacer lo siguiente:

En la plantilla:

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

Y eventualmente:

$scope.phone_with_break = function (x) {
  if (x.phone != "") {
   return x.phone + "<br>";
  }
  return '';
}
SomeDudeSomewhere
fuente
Cómo hacer esto para el editor de summernote, inicialmente obtendré los datos json (que contienen html) del servidor, en summernote estoy usando ng-model. cómo hacer que el código como de confianza a la visualización en el editor summernote
codelearner
Mira esto: 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
fuente
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
fuente
3
No publique solo el código como respuesta, sino que también incluya una explicación de lo que hace su código y cómo resuelve el problema de la pregunta. Las respuestas con una explicación son generalmente de mayor calidad y es más probable que atraigan votos positivos.
Mark Rotteveel