I'm trying to use $sanitize
provider and the ng-bind-htm-unsafe
directive to allow my controller to inject HTML into a DIV.
However, I can't get it to work.
<div ng-bind-html-unsafe="{{preview_data.preview.embed.html}}"></div>
I discovered that it is because it was removed from AngularJS (thanks).
But without ng-bind-html-unsafe
, I get this error:
You can use filter like this
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 "";
};
}
]);
usage
<div ng-bind-html="myData | trustAs"></div>
it can be used for other resource types, for example source link for iframes and other types declared here
I've had a similar problem. Still couldn't get content from my markdown files hosted on github.
After setting up a whitelist (with added github domain) to the $sceDelegateProvider in app.js it worked like a charm.
Description: Using a whitelist instead of wrapping as trusted if you load content from a different urls.
Docs: $sceDelegateProvider and ngInclude (for fetching, compiling and including external HTML fragment)
You indicated that you're using Angular 1.2.0... as one of the other comments indicated, ng-bind-html-unsafe
has been deprecated.
Instead, you'll want to do something like this:
<div ng-bind-html="preview_data.preview.embed.htmlSafe"></div>
In your controller, inject the $sce
service, and mark the HTML as "trusted":
myApp.controller('myCtrl', ['$scope', '$sce', function($scope, $sce) {
// ...
$scope.preview_data.preview.embed.htmlSafe =
$sce.trustAsHtml(preview_data.preview.embed.html);
}
Note that you'll want to be using 1.2.0-rc3 or newer. (They fixed a bug in rc3 that prevented "watchers" from working properly on trusted HTML.)
You do not need to use {{ }} inside of ng-bind-html-unsafe:
<div ng-bind-html-unsafe="preview_data.preview.embed.html"></div>
Here's an example: http://plnkr.co/edit/R7JmGIo4xcJoBc1v4iki?p=preview
The {{ }} operator is essentially just a shorthand for ng-bind, so what you were trying amounts to a binding inside a binding, which doesn't work.
For me, the simplest and most flexible solution is:
<div ng-bind-html="to_trusted(preview_data.preview.embed.html)"></div>
And add function to your controller:
$scope.to_trusted = function(html_code) {
return $sce.trustAsHtml(html_code);
}
Don't forget add $sce
to your controller's initialization.
Strict Contextual Escaping can be disabled entirely, allowing you to inject html using ng-html-bind
. This is an unsafe option, but helpful when testing.
Example from the AngularJS documentation on $sce
:
angular.module('myAppWithSceDisabledmyApp', []).config(function($sceProvider) {
// Completely disable SCE. For demonstration purposes only!
// Do not use in new projects.
$sceProvider.enabled(false);
});
Attaching the above config section to your app will allow you inject html into ng-html-bind
, but as the doc remarks:
SCE gives you a lot of security benefits for little coding overhead. It will be much harder to take an SCE disabled application and either secure it on your own or enable SCE at a later stage. It might make sense to disable SCE for cases where you have a lot of existing code that was written before SCE was introduced and you're migrating them a module at a time.
The best solution to this in my opinion is this:
Create a custom filter which can be in a common.module.js file for example - used through out your app:
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);
};
}])
Usage:
<span ng-bind-html="yourDataValue | html"></span>
Now - I don't see why the directive ng-bind-html
does not trustAsHtml
as part of its function - seems a bit daft to me that it doesn't
Anyway - that's the way I do it - 67% of the time, it works ever time.
Instead of declaring a function in your scope, as suggested by Alex, you can convert it to a simple filter :
angular.module('myApp')
.filter('to_trusted', ['$sce', function($sce){
return function(text) {
return $sce.trustAsHtml(text);
};
}]);
Then you can use it like this :
<div ng-bind-html="preview_data.preview.embed.html | to_trusted"></div>
And here is a working example : http://jsfiddle.net/leeroy/6j4Lg/1/
You can create your own simple unsafe html binding, of course if you use user input it could be a security risk.
App.directive('simpleHtml', function() {
return function(scope, element, attr) {
scope.$watch(attr.simpleHtml, function (value) {
element.html(scope.$eval(attr.simpleHtml));
})
};
})
Source: Stackoverflow.com