I have built a wordpress plugin where users can insert the google map code like this one:
<iframe src="https://www.google.com/maps/embed?pb=xxxxx" width="100%" height="100%" frameborder="0" style="border:0"></iframe>
this code is stored in wp-database and I try to get it from inside my angularjs code..
getMaps();
function getMaps(){
$http.post("wp-content/themes/koplan/pages/getMaps.php").success(function(mapsdata){
$scope.maps = mapsdata;
});
};
My question is: How can I bind/render the iframe in front-end php/html? I've tried <div ng-bind-html=maps> but nothing showed up.
Is there anyother way?? Please help me, Thanks
Probably what you need is sce since I guess your iframe is not accepted as a trusted HTML.
So, after including sce into your controller like
app.controller("MainController", ['$scope', '$http','$sce', function($scope, $http, $sce){
, you would do
$scope.maps = $sce.trustAsHtml(mapsdata);
See this question/answer also.
Also, for other HTML data that you are sure are 'safe' to display, you can use this filter:
app.filter('unsafe', function($sce) {
return function(val) {
return $sce.trustAsHtml(val);
};
});
You can use it with
ng-bind-html="yourHTMLdataVariable | unsafe"
Related
I want to show messages to the end user, just like Google, at the top center of the web panel.
I don't want to include the HTML and related script everywhere in every form and list and chart that I have. I want to centralize this messaging functionality into a service (in Angular JS term) that can be used everywhere.
And just like Google, I want to be able to show rich text in my messages, that is, I want to include links and probably other HTML stuff there. For example instead of showing Customer is defined, I want to show Customer is defined, <a href='#/customer/addPhone'>Now add a phone</a> to guide the user.
What I've done is to place the messages HTML in the root layout of my single paged application:
<div class="appMessages">
<span ng-show="message" ng-click="clearMessage()" ng-bind-html="message"></span>
</div>
and in our controllers, we inject the $rootScope and try to set the message property on it.
Yet I get no results. Can you guide me please?
As a general best practice I would avoid using $rootScope to pass the messages but rather use a dedicated service to update the message,
On your case the problem might be that you need to use angular $sce service to mark your html as trusted.
or load ng-santizemodule instead (which is a seperate module you need to load see offical doc)
That is needed because angular security requires you to explicitly check the html, if the source of your messages are from your code only, and not users inupts you can use the trustAsHtml as you know for sure it a safe html.
On your controller inject $sce, and bind it to your scope, and then use the $sce.trustAsHtml(value) function.
<div class="appMessages">
<span ng-show="message" ng-click="clearMessage()" ng-bind-html="$sce.trustAsHtml(message)"></span>
</div>
angular.module('app', [])
.component('message', {
controller: function($sce, messagService){
this.messagService = messagService;
this.$sce = $sce;
},
template: '{{$ctrl.message}}<div ng-bind-html="$ctrl.$sce.trustAsHtml($ctrl.messagService.message)"></div>'
})
.service('messagService', function(){
this.message = '';
this.updateMessage = function(message){
this.message = message;
}
})
.controller('mainCtrl', function($scope, messagService){
$scope.updateMessage = function () {
messagService.updateMessage('wow <b style="color:yellow;">shiny</b> message');
};
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div ng-controller="mainCtrl" ng-app="app">
<message></message>
<button type="button" ng-click="updateMessage()"> update message</button>
</div>
This question already has answers here:
Insert HTML into view from AngularJS controller
(17 answers)
Closed 7 years ago.
Actually im searching about how i can transform my variable into Html, this variable contain a embed code from instagram.
in my controller
instaembed.controler "instaCtrl", ($scope, $http) ->
#instagram embed get example from insta
$http.get ("http://api.instagram.com/oembed?url=http://instagr.am/p/fA9uwTtkSN/")
.success(data) ->
$scope.html = data.html
...
the result in $scope.html contain a blockquote with many div and image
i've tested it in the view (with ngsanitize), but it show only the text and not the image.
Anyone have an idea about how to get it ? :D
thank you (sorry for my english).
You will have to use Angular's built in Strict Contextual Escaping $sce
$sce Documentation
Then, in your controller:
instaembed.controler "instaCtrl", ($scope, $http, $sce) ->
#instagram embed get example from insta
$http.get ("http://api.instagram.com/oembed?url=http://instagr.am/p/fA9uwTtkSN/")
.success(data) ->
$scope.html = $sce.trustAsHtml(data.html);
...
You need to use ngBindHtml directive.
https://docs.angularjs.org/api/ng/directive/ngBindHtml
<div ng-bind-html-unsafe="html"></div>
Where html is your $scope.html variable. This will render inside div what your variable contains.
function testCtrl($scope) {
$scope.html = "<strong>Hello world!</strong>"
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
<div ng-controller="testCtrl" ng-app>
<div ng-bind-html-unsafe="html"></div>
</div>
You should use ng-bind-html
<span ng-bind-html="your scope variable"></span>
I've ran into a bit of a problem, wherein I've created a $scope.msg and it's printing to my console just fine, but it won't render itself on the DOM. I'm using Browserify to require angular and bundle my js.
index.html
<body ng-app="zeroApp" ng-controller="MainCtrl">
<div class="container">
<div class="item">
<h1>{{ msg }}</h1>
</div>
</div>
<script src="./js/app.js"></script>
</body>
app.js
(function() {
'use strict';
var angular = require('angular');
angular.module('zeroApp', [])
.controller('MainCtrl', ['$scope', function($scope) {
$scope.msg = "Hello Angular!";
console.log($scope.msg);
}]);
})();
Any reason why this isn't being exposed to the DOM and my <h1> element is empty?
Any help is appreciated. Thanks in advance!
Unfortunately I'm not an Angular expert so I can't explain the details, but the problem is that Angular wont detect that change, and thus it wont be propagated into the view. There are other ways around it, but one rather simple fix is to wrap the message into an extra object. Instead of using $scope.msg, try using $scope.msg.txt and it should work.
Hopefully someone with more knowledge of Angular's inner workings can clarify this further.
Here's another Fiddle to demonstrate: http://jsfiddle.net/29Luq8ns/1/
Notice I'm using $timeout in it. That's another way you could work around the problem. By changing $scope.msg inside a $timeout function, it will work, even without a delay parameter.
Figured it out. I was using Swig in my gulpfile.js to do render my HTML templates. The mustache templating language of Swig must have been conflicting with Angular's templating lang. Took it out of my build process and it works like a charm.
Thanks for all the help.
I used ng-bind-html in order to prevent cross site scripting,
read about sanitize and found this discussion and another good discussion.
Although, i did't work for me, can you please help me in figure out why?
HTML:
<p class="big-text" ng-bind-html="to_trusted(message)">
JS:
$scope.to_trusted = function(html_code) {
return $sce.trustAsHtml(html_code);
};
when i'm adding the following line
<img src="x" onerror="alert('cross')">
and adding it to a message i can see it rendered in the DOM, and when i'm refreshing the page i can see the message.
and the popup is shown:
can you please tell me what am i doing wrong?
First of all, it's not XSS on its own.
Second, $sce.trustAsHtml does exactly the opposite of what you thought - it, in fact, instructs Angular to "trust" that the HTML is safe - not to sanitize.
To sanitize, you need to add ngSanitize as a dependency to your app, and ng-bind-html directly to html_code (without to_trusted).
angular.module("myApp", ["ngSanitize"])
.controller("MainCtrl", function($scope){
$scope.html_code = '<img src="x" onerror="alert(\'cross\')">';
});
And in the HTML:
<div ng-bind-html="html_code"></div>
After using Sanitize i change my code and used getTrustedHtml instead trustAsHtml, it runs the sanitize on controller.
$scope.to_trusted = function(html_code) {
return $sce.getTrustedHtml(html_code);
};
And it solves my issue.
This question already has an answer here:
Unable to load url into iframe via AngularJS controller
(1 answer)
Closed 8 years ago.
I am attempting to set the ng-src of an iframe using a scope variable and it keeps coming through as blank.
I tried this:
<div ng-repeat="url in urls">
<div ng-click="testAlert(url.domain)">
<iframe ng-src="{{ url.domain }}" ></iframe>
<div style="text-align: center">{[ url.domain ]}</div>
</div>
</div>
The text shows up just fine, so I know the values are there as well as the click alerts the select domain. It is just the ng-src seems to end up blank and therefore doesn't pull up the site. If I hard code the ng-src to an external site it works.
Most likely has to do with $sce not being configured to trust the external resource when interpolated... Try putting this in your controller (be sure to inject $sce service). trustAsResourceUrl is the method you will be interested in and you would pass the URL you want to use to that:
.controller("MainController", function ($scope, $sce) {
var urls = [];
//Need to trust resource to be able to interpolate, see $sce documentation
urls.push({domain: $sce.trustAsResourceUrl("http://angularjs.org")});
urls.push({domain: $sce.trustAsResourceUrl("http://www.jquery.com")});
$scope.urls = urls;
$scope.testAlert = function (value) {
alert(value);
}
});
See working fiddle.