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?

timhaak
źródło

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]
 }]);
Nenad
źródło
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>
Chris
źródło
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);
}]);
Michael J. Calkins
źródło
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
nguyên
źródło
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>
STAL
źródło
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

Adrian Enriquez
źródło
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>
wcc526
źródło
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 '';
}
SomeDudeSomewhere
źródło
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ń
Sprawdź to: 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
źródło
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
źródło
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