Як ви використовуєте $ sce.trustAsHtml (рядок) для копіювання ng-bind-html-небезпечно в кутовій 1.2+


226

ng-bind-html-unsafe було видалено у куті 1.2

Я намагаюся реалізувати щось там, де мені потрібно скористатися ng-bind-html-unsafe. У документах і на комітеті github кажуть:

ng-bind-html забезпечує ng-html-bind-небезпечну поведінку (внутрішнійHTML - результат без санітарії), коли він прив'язується до результату $ sce.trustAsHtml (рядок).

Як це зробити?


Відповіді:


245

Це повинно бути:

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

плюс у вашому контролері:

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

замість старого синтаксису, де можна було посилатися на $scope.htmlзмінну безпосередньо:

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

Як зазначали кілька коментаторів, $sceйого потрібно вводити в контролер, інакше ви отримаєте $sce undefinedпомилку.

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

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

10
Як ви можете це зробити зі значенням, поверненим функцією? <p ng-bind-html = ""> {{description (category.id)}} </p>
dasper

2
Не впевнений, чи правильно я тебе зрозумів, але: <p ng-bind-html="trustedHtml"></p> і$scope.trustedHtml = $sce.trustAsHtml(description(category.id));
Ненад

1
Я люблю тебе за відгук! Мабуть, проблемою я користувався 1.0.8. У мене є форма з динамічною кількістю розділів, тому при зміні я хотів показати належний опис. <p ng-bind-html="description(category.id)"></p>то останній рядок функції:return $sce.trustAsHtml(value);
Даспер

2
Але ... var x = sce.trustAsHtml ('foo'); var y = sce.trustAsHtml ('foo'); х == у; false ... Так чи не слід створювати нескінченний цикл дайвінгу, оскільки ваша функція повертає новий об'єкт?
рич

25
Також варто згадати, що $ sce потрібно передати в контролер, або ви отримаєте $ sce не визначено
isimmons

633

Фільтр

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

Використання

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

1
Навіщо тобі ngSanitizeтут потрібно ?

2
@OliverJosephAsh, оскільки послуга $ sce визначена в ngSanitize. вони розбивали основні функціональні можливості, тому ми можемо використовувати кутові лише трохи, і не завжди потрібно використовувати весь фреймворк.
Кріс Саттінгер

1
Мені було цікаво, які можуть бути наслідки для безпеки такого подібного? Я попросив додаткових роз'яснень в окремому запитанні . Весь внесок оцінений!
Філіп Буллі

9
@felix у версії 1.2 (коли вони додали це) він за замовчуванням увімкнено як частину ядра, ні ngSanitize, тому немає необхідностіngSanitize
TheSharpieOne

2
Це дизайнерське рішення, прийняте командою кутових - ось як слід реалізувати фільтри - якщо ви зробите це інакше, вони не працюватимуть. Причина, по якій ця функція повинна повернути функцію, полягає в тому, що кутовий може затримати обробку, поки «не знайде потрібний момент». Інакше фреймворк не вплине на те, коли викликається фільтр. Це і добре, і погано, але, наскільки я можу сказати, - потрібно впоратися з хитрою обробкою куточків. Більше інформації тут: docs.angularjs.org/api/ng/provider/$filterProvider
Кріс

16

Особисто я переношу всі свої дані в деякі бібліотеки PHP перед тим, як потрапити в базу даних, тому немає потреби в іншому XSS-фільтрі для мене.

Від 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 || '');
        });
    }
}]);

Використовувати:

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

Щоб відключити $sce:

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

Мені незрозуміло, в чому різниця між двома прикладами. У одного з членів нашої команди є проблема, коли вони мають System.out.println (& ldquo; Привіт, світ! & Rdquo;); в базі даних. Вона використовує <div data-ng-bind-html = "text"> </div> і відображається на сторінці як: System.out.println (& ldquo; Hello World! & Rdquo;) ;. Ви хочете сказати, що використання вашої директиви ngBindHtmlUnsafe вирішить цю проблему?
Alan2

@Alan Я вважаю, що це працювало б, якщо це було <script>System.out.printIn("Hello World!");</script>, я не пробував це особисто, тому що мій PHP видалив усі JS з введення користувача. Я видалив свій другий приклад, тому що рідний Angular є кращим у всіх відношеннях, просто використовуйте цей.
Майкл Дж. Калкінс

Як зробити це для редактора summernote, спочатку я отримаю дані json (які містять html) від сервера, в summernote я використовую ng-модель. як зробити код як довірений для відображення в редакторі
summernote

8

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

1. використовувати фільтр

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

використовуючи (html):

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

2. використовувати ngSanitize: безпечніше

включати angular-sanitize.js

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

додати ngSanitizeв корінну кутову програму

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

використовуючи (html):

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

Як зробити це для редактора summernote, спочатку я отримаю дані json (які містять html) від сервера, в summernote я використовую ng-модель. як зробити код як довірений для відображення в редакторі
summernote

7

Просто створення фільтра зробить трюк. (Відповів за кутовий 1.6)

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

І використовуйте це як слід у html.

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

Цей виправляє помилку з зневагою: "Невідомий постачальник: eProvider <- e <- unsafeFilter"
Валера Тумаш

3

Якщо ви хочете повернути стару директиву, ви можете додати її у свій додаток:

Директива:

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

Використання

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

Джерело - https://github.com/angular-ui/bootstrap/isissue/813


Не поводиться так само.
Кейсі

Як зробити це для редактора summernote, спочатку я отримаю дані json (які містять html) від сервера, в summernote я використовую ng-модель. як зробити код як довірений для відображення в редакторі
summernote

3

JavaScript

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

HTML

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

Як зробити це для редактора summernote, спочатку я отримаю дані json (які містять html) від сервера, в summernote я використовую ng-модель. як зробити код як довірений для відображення в редакторі
summernote

1

Для Rails (принаймні в моєму випадку), якщо ви використовуєте дорогоцінний камінь angularjs-rails , будь ласка, не забудьте додати модуль sanitize

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

А потім завантажте його у своєму додатку ...

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

Тоді ви можете зробити наступне:

На шаблоні:

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

І врешті:

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

Як зробити це для редактора summernote, спочатку я отримаю дані json (які містять html) від сервера, в summernote я використовую ng-модель. як зробити код як довірений для відображення в редакторі
summernote


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
Будь ласка, не публікуйте лише код як відповідь, але також додайте пояснення, що робить ваш код і як він вирішує проблему. Відповіді з поясненням, як правило, вищої якості і, швидше за все, залучають відгуки.
Марк Роттвел
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.