7

I have a datasource that is used to render blog articles on a page. One of the entries contains an IFRAME. I see the IFRAME being returned in the datasource but it is never rendered to the page in the ng-bind-html.

This is my code:

<div class="blog-post-content" ng-bind-html="entry.content" itemprop="text">
</div>

If I switch this to the following, I see the IFRAME tag rendered out, but of course now it is RAW HTML.

<div class="blog-post-content" itemprop="text">
    {{entry.content}}
</div>

How can I get this IFRAME to be rendered to the page.

eat-sleep-code
  • 4,753
  • 13
  • 52
  • 98

1 Answers1

7

The best approach here is to refactor your data source to only contain the URL, rather than the full iframe tag, and use <iframe ng-src="entry.content"></iframe>.

ng-bind-html isn't working for you because the sanitizer is protecting you from potential XSS attacks.

If you don't control the data source, but trust it completely, you can look into using e.g. scope.trustedContent = $sce.trustAsHtml(entry.content); in your directive, and <div ng-bind-html="trustedContent"></div> in the DOM.

(Not controlling it but trusting it completely is, of course, a contradiction in terms, so you may be better off parsing the data source inside your directive to extract the url, rather than trusting the entire string.)

Daniel Beck
  • 20,653
  • 5
  • 38
  • 53
  • "entry" isn't defined until the DOM. Here is my directive: app.controller('BlogController', ["$scope", "$routeParams", "$http", "$sce" function($scope, $routeParams, $http, $sce) { $scope.post = $routeParams.postID; $http({method: 'GET', url: mongoRoot + '/blog'}). success(function(data, status) { $scope.data = data; $scope.status = status; $scope.trustedContent = $sce.trustAsHtml(?????); }); }]); Nothing I put in place of the ????? seems to work. I have tried entry.content, data, data.content, content. – eat-sleep-code Jul 06 '15 at 18:21
  • In that context you'd use `$scope.trustedContent = $sce.trustAsHtml(data.entry.content)` (or whichever portion of the returned data you're looking for.) – Daniel Beck Jul 06 '15 at 18:25
  • But "entry" does not exist in the directive. I can get to a singular content item via data[0].content, etc. "entry" is exposed in the view via data-ng-repeat="entry in data" – eat-sleep-code Jul 07 '15 at 01:16
  • Okay. "or whichever portion of the returned data you're looking for," then. – Daniel Beck Jul 07 '15 at 11:38
  • 1
    I actually found this solution which appears to work. http://stackoverflow.com/a/28363755/3389346 Thanks for your help and time. – eat-sleep-code Jul 07 '15 at 16:12
  • That "solution" is to bypass the html sanitizer, opening your site to potential XSS attacks. You probably shouldn't do that. – Daniel Beck Feb 09 '17 at 15:10