19

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

3
  • @Donal how is that helpful? 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 Commented Jun 8, 2015 at 15:25
  • @pankajparkar I am using 1.3.15 Commented Jun 8, 2015 at 15:50

4 Answers 4

9
+75

Yes 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

Sign up to request clarification or add additional context in comments.

9 Comments

That is very good and detailed answer, thank you for that, unfortunately it deals only with one case - urls. What I really need though is HTML. Also you are using angular directives, I need it 100% without directives. You can see that in my question description. But you might be right and I might have run into case when even disabeling $sce doesn't do anything. - I will chekc if I have same version of angular and sanitize
@Tom, agreed, this is only 1 use case. But I didn't have your use case to demonstrate. The reason is b/c {{greeting}}. I changed Plunker 2, to simply user src="{{movie.src}}", and created the same error. I should have used src rather than ng-src considering your concerns. I chose the use case of ng-src because passing interpolated strings to ng-src is the most strictly enforced SCE behavior whereas, straight interpolation {{greeting}} is the least enforced and usually just succeeds. So without your specific use case (the data that causes break) I would not have caused an error.
@Tom, try the new Plunker using just src="{{movie.src}}" and give me more specifics of the html that causes the SCE error plnkr.co/edit/GFRpFqysxiuGHH9i2QHb?p=preview
But I am not trying to do anything with src... just wrap your movie.title in <h1> tag: $scope.movie = {title: '<h1>Whatever</h1>'} and you will see that on page you will get the tags printed out , not rendered html
@Tom impossible to compile HTML in angular without using a Directive
|
2

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/

6 Comments

That's weird, I used it sparingly in a recent project. Does it fail silently or returns some error? Do you have any clue at all of why it doesn't work?
trustAsHtml works to disable SCE, It will not compile. HTML cannot be "fed" to a browser with AngularJS. Angular does not work with passive templating. The framework circumvents the browser's HTML interpreter.
I've included a link to a fiddle in my answer that shows how it works.
You are using a directive ng-bind-html. This directive specifically compiles the contents to HTML. Directives are the only way to compile strings to Markup in AngularJS. OP apparently cannot use any directives for this solution. Check his first comment on my answer I need it 100% without directives. Otherwise, his original approach of disabling SCE would make trust unnecessary.
No, it wasn't obvious at all. I realized it only after OP's response. The Question is misleading b/c OP is still learning Angular. Your answer (as applied to Question formed) is very good. I wish more of the 5 digit rep users were as thorough.
|
0

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

1 Comment

Tried that, still doesnt work. I have done a lot of digging into angular code, and it seems that angular automatically replaces every {{}} expression with text node which basically prevents the HTML render. would that be possible?
-1

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/

1 Comment

So you are bypassing the whole Angular pipeline and executing that code? So the HTML is not tracked and angular becomes useless. So we're backed to doing jQuery code now.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.