With ng-bind-html-unsafe removed, how do I inject HTML?

HtmlAngularjs

Html Problem Overview


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:

http://errors.angularjs.org/undefined/$sce/unsafe

Html Solutions


Solution 1 - Html

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/

Solution 2 - Html

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.)

Solution 3 - Html

  1. You need to make sure that sanitize.js is loaded. For example, load it from https://ajax.googleapis.com/ajax/libs/angularjs/[LAST_VERSION]/angular-sanitize.min.js
  2. you need to include ngSanitize module on your app eg: var app = angular.module('myApp', ['ngSanitize']);
  3. you just need to bind with ng-bind-html the original html content. No need to do anything else in your controller. The parsing and conversion is automatically done by the ngBindHtml directive. (Read the How does it work section on this: $sce). So, in your case <div ng-bind-html="preview_data.preview.embed.html"></div> would do the work.

Solution 4 - Html

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.

Solution 5 - Html

The best solution to this in my opinion is this:

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

Solution 6 - Html

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

Solution 7 - 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.

Solution 8 - Html

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)

Solution 9 - Html

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.

Solution 10 - Html

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmetalaureateView Question on Stackoverflow
Solution 1 - HtmlLeeroy BrunView Answer on Stackoverflow
Solution 2 - HtmlijprestView Answer on Stackoverflow
Solution 3 - Htmlp.matsinopoulosView Answer on Stackoverflow
Solution 4 - HtmlAlexView Answer on Stackoverflow
Solution 5 - HtmlPaulView Answer on Stackoverflow
Solution 6 - HtmlJason GoemaatView Answer on Stackoverflow
Solution 7 - HtmlksimonsView Answer on Stackoverflow
Solution 8 - HtmlLahmizzarView Answer on Stackoverflow
Solution 9 - HtmlSean FaheyView Answer on Stackoverflow
Solution 10 - HtmlBotanManView Answer on Stackoverflow