Я пытаюсь использовать $sanitize
provider и директиву ng-bind-htm-unsafe
, чтобы мой контроллер мог вводить HTML в DIV.
Однако я не могу заставить его работать.
<div ng-bind-html-unsafe="{{preview_data.preview.embed.html}}"></div>
Я обнаружил, что это потому, что он был удален из AngularJS (спасибо).
Но без ng-bind-html-unsafe
, я получаю эту ошибку:
ngSanitize
на ваш app
например: var app = angular.module('myApp', ['ngSanitize']);
ng-bind-html
исходным html
контентом. Не нужно ничего делать в контроллере. Разбор и преобразование автоматически выполняются директивой ngBindHtml
. (Прочитайте раздел How does it work
по этому вопросу: $sce). Итак, в вашем случае <div ng-bind-html="preview_data.preview.embed.html"></div>
выполнит эту работу.Вместо объявления функции в вашей области действия, как было предложено Алексом, вы можете преобразовать ее в простой фильтр:
angular.module('myApp')
.filter('to_trusted', ['$sce', function($sce){
return function(text) {
return $sce.trustAsHtml(text);
};
}]);
Затем вы можете использовать его следующим образом:
<div ng-bind-html="preview_data.preview.embed.html | to_trusted"></div>
И вот рабочий пример: http://jsfiddle.net/leeroy/6j4Lg/1/
Вы указали, что используете Angular 1.2.0... как один из других отмеченных комментариев, ng-bind-html-unsafe
устарел.
Вместо этого вы захотите сделать что-то вроде этого:
<div ng-bind-html="preview_data.preview.embed.htmlSafe"></div>
В вашем контроллере вставьте службу $sce
и отметьте HTML как "доверенный":
myApp.controller('myCtrl', ['$scope', '$sce', function($scope, $sce) {
// ...
$scope.preview_data.preview.embed.htmlSafe =
$sce.trustAsHtml(preview_data.preview.embed.html);
}
Обратите внимание, что вы захотите использовать 1.2.0-rc3 или новее. (Они зафиксировали ошибку в rc3, которая помешала "наблюдателям" корректно работать с надежным HTML.)
myApp.controller('myCtrl', ['$scope', '$sce', function($scope, $sce) {
Для меня самое простое и гибкое решение:
<div ng-bind-html="to_trusted(preview_data.preview.embed.html)"></div>
И добавьте функцию к контроллеру:
$scope.to_trusted = function(html_code) {
return $sce.trustAsHtml(html_code);
}
Не забудьте добавить $sce
к инициализации вашего контроллера.
Лучшим решением для этого, на мой взгляд, является следующее:
Создайте настраиваемый фильтр, который может быть, например, в файле common.module.js - используется через ваше приложение:
var app = angular.module('common.module', []);
// html filter (render text as html)
app.filter('html', ['$sce', function ($sce) {
return function (text) {
return $sce.trustAsHtml(text);
};
}])
Применение:
<span ng-bind-html="yourDataValue | html"></span>
Теперь - я не понимаю, почему директива ng-bind-html
не является trustAsHtml
как часть ее функции - кажется мне немного глупой, что она не
В любом случае - так, как я это делаю - 67% времени, он работает всегда.
Вы можете создать свою собственную небезопасную привязку html, конечно, если вы используете пользовательский ввод, это может быть угрозой безопасности.
App.directive('simpleHtml', function() {
return function(scope, element, attr) {
scope.$watch(attr.simpleHtml, function (value) {
element.html(scope.$eval(attr.simpleHtml));
})
};
})
$sce.trustAsHtml
?
Вам не нужно использовать {{}} внутри ng-bind-html-unsafe:
<div ng-bind-html-unsafe="preview_data.preview.embed.html"></div>
Вот пример: http://plnkr.co/edit/R7JmGIo4xcJoBc1v4iki?p=preview
Оператор {{}} по существу является просто сокращением для ng-bind, поэтому то, что вы пытались, представляет собой привязку внутри привязки, которая не работает.
Вы можете использовать фильтр, подобный этому
angular.module('app').filter('trustAs', ['$sce',
function($sce) {
return function (input, type) {
if (typeof input === "string") {
return $sce.trustAs(type || 'html', input);
}
console.log("trustAs filter. Error. input isn't a string");
return "";
};
}
]);
Использование
<div ng-bind-html="myData | trustAs"></div>
он может использоваться для других типов ресурсов, например исходная ссылка для iframes и других типов, объявленных здесь
У меня была аналогичная проблема. Все еще не удалось получить контент из моих файлов разметки, размещенных на github.
После настройки белого списка (с добавленным доменом github) в $sceDelegateProvider в app.js он работал как шарм.
Описание: использование белого списка вместо обертывания как надежного, если вы загружаете контент из разных URL-адресов.
Документы: $sceDelegateProvider и ngInclude (для извлечения, компиляции и включения внешнего HTML-фрагмента)
Строгое контекстное экранирование может быть полностью отключено, что позволяет вам вводить html с помощью ng-html-bind
. Это небезопасный вариант, но полезно при тестировании.
Пример из Документация AngularJS на $sce
:
angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) {
// Completely disable SCE. For demonstration purposes only!
// Do not use in new projects.
$sceProvider.enabled(false);
});
Прикрепление вышеуказанного раздела конфигурации к вашему приложению позволит вам вставить html в ng-html-bind
, но, как замечает doc:
SCE дает вам много преимуществ по безопасности для небольших накладных расходов на кодирование. Будет гораздо сложнее принять приложение, отключенное SCE, и либо закрепите его самостоятельно или включите SCE на более позднем этапе. Это может сделать смысл отключить SCE для случаев, когда у вас много существующего кода которое было написано до введения SCE, и вы переносите их модуль за раз.