Jak używać $ sce.trustAsHtml (string) do replikacji ng-bind-html-niebezpiecznego w Angular 1.2+


226

ng-bind-html-unsafe został usunięty w Angularze 1.2

Próbuję wdrożyć coś, co muszę użyć ng-bind-html-unsafe. W dokumentach i na github commit mówią:

ng-bind-html zapewnia zachowanie podobne do ng-html-bind-niebezpiecznych (wynik wewnętrzny bez HTMLHitml bez sanityzacji), gdy jest powiązany z wynikiem $ sce.trustAsHtml (string).

Jak Ty to robisz?


Odpowiedzi:


245

To powinno być:

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

plus w twoim kontrolerze:

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

zamiast starej składni, w której można odwoływać się $scope.htmlbezpośrednio do zmiennej:

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

Jak zauważyło kilku komentujących, $scenależy wprowadzić je do sterownika, w przeciwnym razie wystąpi $sce undefinedbłąd.

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

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

10
Jak możesz to zrobić z wartością zwróconą przez funkcję? <p ng-bind-html = ""> {{description (category.id)}} </p>
— dasper

2
Nie jestem pewien, czy dobrze zrozumiałem, ale: <p ng-bind-html="trustedHtml"></p> i$scope.trustedHtml = $sce.trustAsHtml(description(category.id));
— Nenad,

1
Kocham cię za odpowiedź! Najwyraźniej problem polegał na tym, że używałem 1.0.8. Mam formularz z dynamiczną liczbą sekcji, więc przy zmianie chciałem pokazać odpowiedni opis. <p ng-bind-html="description(category.id)"></p>następnie ostatni wiersz funkcji:return $sce.trustAsHtml(value);
— dasper

2
Ale ... var x = sce.trustAsHtml ('foo'); var y = sce.trustAsHtml ('foo'); x == y; false ... Czy nie powinno to stworzyć nieskończonej pętli podsumowania, ponieważ funkcja zwraca nowy obiekt?
— rych

25
Warto również wspomnieć, że $ sce musi zostać przekazany do kontrolera lub otrzymasz $ sce nie jest zdefiniowany
— isimmons

633

Filtr

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

Stosowanie

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

1
Dlaczego potrzebujesz ngSanitizetutaj?

2
@OliverJosephAsh, ponieważ usługa $ sce jest zdefiniowana w ngSanitize. rozbiły one główną funkcjonalność, dzięki czemu możemy trochę użyć kątownika i nie zawsze musimy korzystać z całego frameworka.
— Chris Sattinger,

1
Zastanawiałem się, jakie mogą być implikacje bezpieczeństwa dla czegoś takiego? Poprosiłem o więcej wyjaśnień w osobnym pytaniu . Doceniamy wszystkie dane wejściowe!
— Philip Bulley,

9
@ felix w wersji 1.2 (kiedy to dodali) jest domyślnie włączony jako część rdzenia, nie ngSanitize, więc nie ma takiej potrzebyngSanitize
— TheSharpieOne 15.01.2014

2
Jest to decyzja projektowa podjęta przez zespół Angular - w taki sposób należy zastosować filtry - jeśli zrobisz to inaczej, nie będą działać. Powodem, dla którego musi to zwrócić funkcję, jest to, że kąt może opóźnić przetwarzanie, dopóki „nie znajdzie odpowiedniego momentu”. W przeciwnym razie framework nie miałby żadnego wpływu na wywołanie filtra. To zarówno dobre, jak i złe, ale o ile mogę stwierdzić - trzeba poradzić sobie z trudnym przetwarzaniem kątów. Więcej informacji tutaj: docs.quarejs.org/api/ng/provider/$filterProvider
— Chris

16

Osobiście odkażam wszystkie moje dane za pomocą niektórych bibliotek PHP przed wejściem do bazy danych, więc nie potrzebuję dla mnie innego filtra XSS.

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

Używać:

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

Aby wyłączyć $sce:

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

Nie jestem jasne, jaka jest różnica między tymi dwoma przykładami. Jeden z członków naszego zespołu ma problem z System.out.println (& ldquo; Hello World! & Rdquo;); w bazie danych. Używa <div data-ng-bind-html = "text"> </div> i pojawia się na stronie jako: System.out.println (& ldquo; Hello World! & Rdquo;) ;. Czy mówisz, że użycie dyrektywy ngBindHtmlUnsafe rozwiązałoby ten problem?
— Alan2

@Alan Wierzę, że to by działało, gdyby tak było <script>System.out.printIn("Hello World!");</script>, nie próbowałem tego osobiście, ponieważ mój PHP usunął wszystkie JS z danych wejściowych użytkownika. Usunąłem mój drugi przykład, ponieważ natywny Angulara jest lepszy pod każdym względem, tylko go używaj.
— Michael J. Calkins

Jak to zrobić dla edytora summernote, początkowo otrzymam dane json (zawierające html) z serwera, w summernote używam ng-model. jak sprawić, by kod był wyświetlany jako zaufany w edytorze
— summernote

8

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

1. użyj filtra

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

przy użyciu (html):

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

2. użyj ngSanitize: bezpieczniej

zawierać angular-sanitize.js

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

dodaj ngSanitizew aplikacji kątowej root

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

przy użyciu (html):

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

Jak to zrobić dla edytora summernote, początkowo otrzymam dane json (zawierające html) z serwera, w summernote używam ng-model. jak sprawić, by kod był wyświetlany jako zaufany w edytorze
— summernote

7

Po prostu utworzenie filtra załatwi sprawę. (Odpowiedzi na Angular 1.6)

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

I użyj tego w następujący sposób w html.

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

Ten naprawia błąd uglifying: „Nieznany dostawca: eProvider <- e <- unsafeFilter”
— Valera Tumash

3

Jeśli chcesz przywrócić starą dyrektywę, możesz dodać to do swojej aplikacji:

Dyrektywa:

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

Stosowanie

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

Źródło - https://github.com/angular-ui/bootstrap/issues/813


Nie zachowuje się tak samo.
— Casey,

Jak to zrobić dla edytora summernote, początkowo otrzymam dane json (zawierające html) z serwera, w summernote używam ng-model. jak sprawić, by kod był wyświetlany jako zaufany w edytorze
— podsumowań

3

JavaScript

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

HTML

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

Jak to zrobić dla edytora summernote, początkowo otrzymam dane json (zawierające html) z serwera, w summernote używam ng-model. jak sprawić, by kod był wyświetlany jako zaufany w edytorze
— summernote

1

W przypadku Railsów (przynajmniej w moim przypadku), jeśli używasz klejnotu angularjs-rails , pamiętaj, aby dodać moduł dezynfekujący

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

A potem załaduj go do swojej aplikacji ...

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

Następnie możesz wykonać następujące czynności:

Na szablonie:

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

I ostatecznie:

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

Jak to zrobić dla edytora summernote, początkowo otrzymam dane json (zawierające html) z serwera, w summernote używam ng-model. jak sprawić, by kod był wyświetlany jako zaufany w edytorze
— podsumowań


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
Nie zamieszczaj tylko kodu jako odpowiedzi, ale dołącz także wyjaśnienie, co robi Twój kod i jak rozwiązuje problem pytania. Odpowiedzi z wyjaśnieniem są na ogół wyższej jakości i częściej przyciągają entuzjastów.
— Mark Rotteveel
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.