Como você usa $ sce.trustAsHtml (string) para replicar ng-bind-html-unsafe no Angular 1.2+

226

ng-bind-html-unsafe foi removido no Angular 1.2

Estou tentando implementar algo em que preciso usar ng-bind-html-unsafe. Nos documentos e no github, eles dizem:

ng-bind-html fornece um comportamento semelhante a ng-html-bind-inseguro (innerHTML é o resultado sem higienização) quando associado ao resultado de $ sce.trustAsHtml (string).

Como você faz isso?

timhaak
fonte
possível duplicar de Inserir HTML na exibição usando AngularJS #
31414

Respostas:

245

Isso deve ser:

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

mais no seu controlador:

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

em vez da sintaxe antiga, onde você pode fazer referência $scope.htmldiretamente à variável:

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

Como vários comentadores apontaram, $scedeve ser injetado no controlador, caso contrário, você receberá um $sce undefinederro.

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

 myApp.controller('MyController', ['$sce', function($sce) {
    // ... [your code]
 }]);
Nenad
fonte
10
Como você pode fazer isso com um valor retornado por uma função? <p ng-bind-html = ""> {{description (category.id)}} </p>
dasper
2
Não tenho certeza se eu entendi direito, mas: <p ng-bind-html="trustedHtml"></p> e$scope.trustedHtml = $sce.trustAsHtml(description(category.id));
Nenad
1
Eu te amo por responder! Aparentemente, o problema era eu usando o 1.0.8. Eu tenho um formulário com número dinâmico de seções, então, na mudança, eu queria mostrar a descrição adequada. <p ng-bind-html="description(category.id)"></p>então a última linha da função:return $sce.trustAsHtml(value);
dasper
2
Mas ... var x = sce.trustAsHtml ('foo'); var y = sce.trustAsHtml ('foo'); x == y; false ... Portanto, isso não deveria criar um loop de resumo infinito, pois sua função retorna um novo objeto?
rych 01/10
25
Também vale a pena mencionar que $ sce precisa ser passado para o controlador ou você recebe $ sce não está definido
isimmons
634

Filtro

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

Uso

<ANY ng-bind-html="value | unsafe"></ANY>
Chris
fonte
1
Por que você precisa ngSanitizeaqui?
2
@OliverJosephAsh porque o serviço $ sce está definido em ngSanitize. eles separaram as principais funcionalidades, para que possamos usar um pouco de angular e nem sempre precisamos usar toda a estrutura.
precisa saber é o seguinte
1
Fiquei me perguntando o que as implicações de segurança de algo como isso pode ser? Pedi mais esclarecimentos em uma pergunta separada . Toda a entrada apreciada!
precisa saber é o seguinte
9
@felix na versão 1.2 (quando adicionado este) é ativado por padrão como parte do core, não ngSanitize, por isso não há necessidade dengSanitize
TheSharpieOne
2
Essa é uma decisão de design tomada pela equipe angular - é assim que os filtros devem ser implementados - se você fizer isso de outra forma, eles não funcionarão. A razão pela qual isso deve retornar uma função é que o angular pode atrasar o processamento até 'encontrar o momento certo'. Caso contrário, a estrutura não teria nenhuma influência sobre quando o filtro é chamado. Isso é bom e ruim, mas até onde eu sei - é necessário lidar com o complicado processamento dos angulares. Mais informações aqui: docs.angularjs.org/api/ng/provider/$filterProvider
Chris
16

Pessoalmente, desinfecto todos os meus dados com algumas bibliotecas PHP antes de entrar no banco de dados, para que não haja necessidade de outro filtro XSS para mim.

From 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 desativar $sce:

app.config(['$sceProvider', function($sceProvider) {
    $sceProvider.enabled(false);
}]);
Michael J. Calkins
fonte
Não estou claro qual é a diferença entre os dois exemplos. Um dos membros de nossa equipe tem um problema em que possui System.out.println ("Hello World!"); no banco de dados. Ela está usando <div data-ng-bind-html = "text"> </div> e aparece na página como: System.out.println ("Hello World!"). Você está dizendo que o uso da diretiva ngBindHtmlUnsafe resolveria esse problema?
Alan2
@ Alan Eu acredito que funcionaria se fosse <script>System.out.printIn("Hello World!");</script>, não tentei isso pessoalmente porque meu PHP removeu todas as JS da entrada do usuário. Eu removi meu segundo exemplo, porque o nativo do Angular é superior em todos os aspectos, basta usá-lo.
22813 Michael J. Calkins #
Como fazer isso no editor do summernote, inicialmente receberei os dados do json (que contém html) do servidor, no summernote estou usando o ng-model. como fazer com que o código como confiável para exibição no editor summernote
codelearner
8

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

1. use filtro

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

usando (html):

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

2. use ngSanitize: mais seguro

incluir angular-sanitize.js

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

adicionar ngSanitizeaplicativo angular raiz

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

usando (html):

<span ng-bind-html="line"></span>
==>click `aaa` nothing happen
nguyên
fonte
Como fazer isso no editor do summernote, inicialmente receberei os dados do json (que contém html) do servidor, no summernote estou usando o ng-model. como fazer com que o código como confiável para exibição no editor summernote
codelearner
7

Simplesmente criar um filtro fará o truque. (Respondido para Angular 1.6)

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

E use isso da seguinte forma no html.

<h2 ng-bind-html="someScopeValue | trustHtml"></h2>
AÇO
fonte
Este corrige o erro com uglifying: "Provedor desconhecido: eProvider <- e <- unsafeFilter"
Valera Tumash
3

Se você deseja a diretiva antiga de volta, pode adicioná-la ao seu aplicativo:

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>

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

Adrian Enriquez
fonte
Não se comporta da mesma maneira.
Casey #
Como fazer isso no editor do summernote, inicialmente receberei os dados do json (que contém html) do servidor, no summernote estou usando o ng-model. como fazer com que o código como confiável para exibição no editor summernote
codelearner
3

Javascript

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

HTML

<pre ng-bind-html="get_pre(html)"></pre>
wcc526
fonte
Como fazer isso no editor do summernote, inicialmente receberei os dados do json (que contém html) do servidor, no summernote estou usando o ng-model. como fazer com que o código como confiável para exibição no editor summernote
codelearner
1

Para Rails (pelo menos no meu caso), se você estiver usando a gem angularjs-rails , lembre-se de adicionar o módulo sanitize

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

E carregue-o no seu aplicativo ...

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

Então você pode fazer o seguinte:

No modelo:

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

E eventualmente:

$scope.phone_with_break = function (x) {
  if (x.phone != "") {
   return x.phone + "<br>";
  }
  return '';
}
SomeDudeSomewhere
fonte
Como fazer isso no editor do summernote, inicialmente receberei os dados do json (que contém html) do servidor, no summernote estou usando o ng-model. como fazer com que o código como confiável para exibição no editor summernote
codelearner
Verifique isto: 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
fonte
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
fonte
3
Não publique apenas o código como resposta, mas também inclua uma explicação sobre o que seu código faz e como ele resolve o problema da pergunta. As respostas com uma explicação geralmente são de qualidade superior e têm maior probabilidade de atrair votos positivos.
Mark Rotteveel