Is it possible to completely disable sanitizingof HTML?
What I want to achieve is to have in my controller:
$scope.greeting = '<h2>Hello World</h2>'
And in my view
{{greeting}}
I cannot (and dont want to) use ng-bind-html and such, I want to disable sanitizing all together.
Just to give some more context - I am preparing simple "framework wrap around" for developing a template for specific system.
When you develop template for this system, they have pre-defined snippets that you can place on your page by writing "{{something}}" but it is not running on angular (probably mustache or something).
Now the template can be developed only online and it is VERY user-unfriendly proccess. Therefore I setup simple project in angular with corresponding routes etc, so everyone can develop the template on their machine and then simply copy it over to the system.
That is why in the template files it shouldnt be noticable that its done in angular, it just be as close to their system as possible.
One last note - I did try:
myApp.config(['$sceProvider',function($sceProvider){
$sceProvider.enabled(false);
}]);
Didn't do anything for me
Is it possible to completely disable sanitizingof HTML?
What I want to achieve is to have in my controller:
$scope.greeting = '<h2>Hello World</h2>'
And in my view
{{greeting}}
I cannot (and dont want to) use ng-bind-html and such, I want to disable sanitizing all together.
Just to give some more context - I am preparing simple "framework wrap around" for developing a template for specific system.
When you develop template for this system, they have pre-defined snippets that you can place on your page by writing "{{something}}" but it is not running on angular (probably mustache or something).
Now the template can be developed only online and it is VERY user-unfriendly proccess. Therefore I setup simple project in angular with corresponding routes etc, so everyone can develop the template on their machine and then simply copy it over to the system.
That is why in the template files it shouldnt be noticable that its done in angular, it just be as close to their system as possible.
One last note - I did try:
myApp.config(['$sceProvider',function($sceProvider){
$sceProvider.enabled(false);
}]);
Didn't do anything for me
Share Improve this question asked Jun 8, 2015 at 14:53 TomasTomas 2,7266 gold badges44 silver badges54 bronze badges 3- @Donal how is that helpful? – Tomas Commented Jun 8, 2015 at 15:06
- you need to upgrade your angular version to take use of this feature..you should have angular 1.3+ version – Pankaj Parkar Commented Jun 8, 2015 at 15:25
- @pankajparkar I am using 1.3.15 – Tomas Commented Jun 8, 2015 at 15:50
4 Answers
Reset to default 9 +75Yes you can turn off SCE but this will not cause your strings to be interpolated into HTML
Using your scenario:
$scope.movie = {title:"<h1>Egghead.io AngularJS, Binding</h1>",
src:"http://www.youtube.com/embed/Lx7ycjC8qjE"};
and interpolating the title directly without use of ng-bind-html="movie.title"
<p>{{movie.title}}</p>
will produce this
<h1>Egghead.io AngularJS Binding</h1>
Straight interpolation seems to be sanitized, but it is actually not compiled.
An interpolated string with HTML is treated as a string unless compiled within a directive.
Other frameworks tend to be "string based" (they feed the browser directly), whereas AngularJS is "DOM based", it compiles your HTML and manages it aggressively with scopes and watch events. Martin Fowler refers to this as Template View vs Transform View.
HTML can be compiled within Directives, but can only be interpolated in markup and controllers
I've created 2 Plunkers trying to access an "insecure url" which just means I interpolated a url in ng-src
without using $sce.trustAs
Exhibit 1: Plunker 1 SCE disabled during config
Markup interpolates "insecure url":
<p>{{movie.title}}</p>
<iframe class="youtube-player" type="text/html" width="640" height="385" ng-src="{{movie.src}}" allowfullscreen frameborder="0">
</iframe>
App disables $sceProvider
var app = angular.module('plunker', ['ngSanitize']);
app.config(['$sceProvider',function($sceProvider){
$sceProvider.enabled(false);
}]);
app.controller('MainCtrl', function($scope, $sce) {
$scope.movie = {src:"http://www.youtube.com/embed/Lx7ycjC8qjE", title:"Egghead.io AngularJS Binding"};
});
The "unsafe" URL is interpolated without error. The Video is displayed.
Exhibit 2: Plunker 2 app.config
commented out, ergo, using Default SCE settings
var app = angular.module('plunker', ['ngSanitize']);
//app.config(['$sceProvider',function($sceProvider){
// $sceProvider.enabled(false);
//}]);
app.controller('MainCtrl', function($scope, $sce) {
$scope.movie = {src:"http://www.youtube.com/embed/Lx7ycjC8qjE", title:"Egghead.io AngularJS Binding"};
});
Error:
Error: [$interpolate:interr] Can't interpolate: {{movie.src}} Error: [$sce:insecurl] Blocked loading resource from url not allowed by $sceDelegate policy. URL: http://www.youtube.com/embed/Lx7ycjC8qjE
A while ago I managed to render some HTML returned from a service like this:
$scope.greeting = $sce.trustAsHtml('<h2>Hello World</h2>');
And in your HTML
<div ng-bind-html="htmlGreeting"></div>
Don't forget to inject the $sce service in the controller.
EDIT here's a example fiddle: https://jsfiddle.net/b78hkssn/2/
Try enhance or change standard behavior of $sce using decorators:
angular
.module( appName, [ ] )
.config([ "$provide", function( $provide )
{
// Use the `decorator` to enhance or change behaviors of original service instance;
$provide.decorator( '$sce', [ "$delegate", function( $delegate )
{
// Save the original $sce.parseAsHtml
var parseAsHtml= $sce.parseAsHtml;
$delegate.parseHtml= function( ) {
// Implements your custom behavior...
};
return $delegate;
}]);
}]);
I managed to find another way of solving the problem without using any directives.
Basically I use an injector to use the $compile service.
JS:
angular.injector(['ng']).invoke(function($compile, $rootScope) {
$('.html-content').append($compile('<h2>Hello World</h2>')($rootScope));
});
Here's a demo: https://jsfiddle.net/davguij/tby59sk7/1/