IFrame Not Being Rendered In ng-bind-html
Asked Answered
L

1

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.

Late answered 6/7, 2015 at 16:19 Comment(3)
Seems like a security issue, explained ans solved here.Wite
This solution appears to work. https://mcmap.net/q/108232/-with-ng-bind-html-unsafe-removed-how-do-i-inject-htmlLate
That "solution" is to bypass the html sanitizer, opening your site to potential XSS attacks. You probably shouldn't do that.Antoninus
A
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.)

Antoninus answered 6/7, 2015 at 16:54 Comment(6)
"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.Late
In that context you'd use $scope.trustedContent = $sce.trustAsHtml(data.entry.content) (or whichever portion of the returned data you're looking for.)Antoninus
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"Late
Okay. "or whichever portion of the returned data you're looking for," then.Antoninus
I actually found this solution which appears to work. https://mcmap.net/q/108232/-with-ng-bind-html-unsafe-removed-how-do-i-inject-html Thanks for your help and time.Late
That "solution" is to bypass the html sanitizer, opening your site to potential XSS attacks. You probably shouldn't do that.Antoninus

© 2022 - 2024 — McMap. All rights reserved.