AngularJs sanitizing and displaying html - javascript

I am trying to display dynamically html inside a div. However the div ng-bind-html does not display at all (on firefox, chrome and safari).
Looking at the other posts of this website I saw that I have to include ngSanitize.
I found this snippet here https://www.npmjs.com/package/angular-sanitize :
angular.module('myApp', ['ngSanitize']);
However I do not know where I should write this code ... Do you have any idea how I could do it ?
Thank you very much !
Here is my code :
Code in the component.ts:
import { Component, OnInit, SecurityContext } from '#angular/core';
import { DomSanitizer, SafeHtml } from '#angular/platform-browser';
#Component({
selector: 'app-player-filter',
templateUrl: './player-filter.component.html',
styleUrls: ['./player-filter.component.css']
})
export class PlayerFilterComponent implements OnInit {
text = '<h1>Test</h1><script></script>';
text_sanitized: SafeHtml;
constructor(private _sanitizer: DomSanitizer) { }
ngOnInit() {
this.text_sanitized = this.htmlProperty;
}
public get htmlProperty(): SafeHtml {
return this._sanitizer.sanitize(SecurityContext.HTML, this.text);
}
}
Code in the component.html:
<div ng-bind-html="text_sanitized"></div>
Normal: {{text}} Sanitized: {{text_sanitized}}
Output on firefox:
Normal: <h1>Test</h1><script></script> Sanitized: <h1>Test</h1>
Output console:
WARNING: sanitizing HTML stripped some content (see http://g.co/ng/security#xss).
The console output shows that the sanitizing operation happenned (confirmed by the output sanitized that got rid of the script).
Wierd thing, there is no error shown in the console from having unsafe html displayed...

The 'ng-bind-html' belongs to angularJS(older version before angular 2+) so its not suppose to work or display anything with Angular 6.
Use [innerHTML] instead as mentioned in Agular Documentation:
<div [innerHTML]="text_sanitized"></div>

Related

Angular - How to execute a script stored in a string with InnerHtml

I'm trying to display an html and execute a script which are both stored in a string.
I have created a pipe which transform the string with the this.sanitizer.bypassSecurityTrustHtml() method.
Then, I inject the content of the string in the innerHtml attribute and combine it with my pipe.
You can execute it on stackblitz : https://stackblitz.com/edit/angular-uilj36
This is a part of my code :
safe.pipe.ts
import { Pipe, PipeTransform } from '#angular/core';
import { DomSanitizer, SafeHtml} from '#angular/platform-browser';
#Pipe({
name: 'safe'
})
export class SafePipe implements PipeTransform {
constructor(protected sanitizer: DomSanitizer) {}
transform(value: any, args?: any): any {
return this.sanitizer.bypassSecurityTrustHtml(value);
}
}
app.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
public html = '<div>Html content</div> <script>console.log("run js ok");</script>';
}
app.component.html
<h1>Code injection :</h1>
<div [innerHtml]="html | safe"></div>
The problem is that the script doesn't execute.
Anybody have an idea why the script is not executed ?
PS : I know that it's not recommended but someone asked me to do it :)
You could also use an iFrame instead of a div element. On the iFrame you can set the srcdoc property.
<iframe [srcdoc]="html | safe"></iframe>
it should display and run the html with its scripts.If you want to restrict the iframe you can use the sandbox property.
For your example it could look like this:
<iframe [srcdoc]="html | safe" sandbox="allow-scripts"></iframe>
iframes are made for such security things like executing scripts in an isolated environment.

Angular wrapper of JS library doesn't load styles

I want to use this library https://bootstrap-datepicker.readthedocs.io/en/latest/markup.html#date-range in my application. But it has to be angular component so for the first time in my short career I wanted to create wrapper of library but I think I did something wrong becouse It doesn't looke like original picker.
This is how it should looks like:
And this is how it looks like as my angular component:
Also when I want to select only month or year it looks weird:
Ok so now time to see my component code:
import {AfterViewInit, Component, ElementRef, Input, OnInit} from
'#angular/core';
import 'bootstrap-datepicker';
declare var $;
#Component({
selector: 'cb-daterangepicker',
templateUrl: './daterangepicker.component.html',
styleUrls: ['./daterangepicker.component.scss']
})
export class DaterangepickerComponent implements OnInit, AfterViewInit {
#Input()
datepickerOptions: DatepickerOptions;
constructor(private elementRef: ElementRef) {
}
ngOnInit() {
}
ngAfterViewInit(): void {
// $(this.elementRef.nativeElement).datepicker();
$('.input-daterange input').each(function() {
$(this).datepicker('clearDates');
});
}
}
As You see there is no for example selection of range, or just start and end dates, it simply looks different so I thought it becouse not loaded styles but I might be wrong. I need Your help Guys, maybe my wrapper isn't correctly done?
*Network console with styles:
Addin styles to index.html and angular.json helped with some things:
But still range between dates is not highlighted..
Are you sure that bootstrap is correctly loaded ? you have to check this first and you have to check if the css for the library is loaded afterwards.
try to check that with the browser network console :)
othewise try to call the library style with the cdn :
https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker.min.css

Inline js with Iframe src not working in IE11 with Angular

I have a scenario where i have to embed a inline js to an iframe src by dynamically building the iframe at runtime when the component loads.
The example runs fine in both Chrome and Edge but fails in IE11 , what could be the possible reason? IE dosen't even complain and if we check the console log nothing gets printed, where as in chrome it will print my name in the console log .
Stackblitz link.
Note - Please run the app in chrome as well as IE to see the difference .
import { Component, OnInit, Renderer2, ElementRef } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit{
name = 'Angular 6';
constructor(private renderer : Renderer2, private elRef : ElementRef ){}
ngOnInit(){
const outerDiv = this.elRef.nativeElement.getElementsByTagName('div')[0];
const el = this.renderer.createElement('iframe');
let script =encodeURI(`data:text/html,<script>console.log('DONE');var execute = function(context){ console.log(context.data.name);}; window.addEventListener('message', function(msg){execute(msg);});</script>`);
el.setAttribute('sandbox', 'allow-scripts');
el.setAttribute('src', script);
outerDiv.appendChild(el);
el.onload = function() {
el.contentWindow.postMessage({name: 'Rahul'}, "*");
}
}
}
<div></div>
Due to security reason in IE, you can not give base64 data of any image/ pdf or any other assets to a HTML object. Instead you can use path of the server having the asset.
how to display base64 encoded pdf?
This gives an example.

HTML not interpreted in Angular template

It has been several days since I am stuck on a problem that I do not see where it can come from.
I currently retrieve the content of my article in an observable and I loop over it in the angular template. So far I have no problem I get my information well that I display but the HTML is not interpreted with an innerHTML, nor with a pipe using the DomSanitizer.
I tried to store the information of my observable in a table to see if it does not come from the asynchronous but no.
I saw that it was necessary to use the DomSanitizer to force the security because when the string that contains the HTML is too long (which is my case because it is long paragraphs), the innerHTML has not no effect.
The string fits well in my pipe because when I make a console.log of my variable containing the string, it shows me well in my console with HTML tags around.
If you have any idea where my problem may come from, knowing that I have no errors in the console.
Here is my code without the pipe and HTML not interpreted :
<div *ngFor="let article of informationsArticle|async;">
<div [innerHTML]="article.contenu_part1" *ngIf="article.contenu_part1"></div>
</div>
With the pipe and HTML not interpreted:
<div *ngFor="let article of informationsArticle|async;">
<p [innerHTML]="article.contenu_part1 | keepHtml" *ngIf="article.contenu_part1"></p>
</div>
The pipe code :
import { Pipe, PipeTransform } from '#angular/core';
import { DomSanitizer } from '#angular/platform-browser';
#Pipe({ name: 'keepHtml', pure: false })
export class EscapeHtmlPipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) {
}
transform(content) {
return this.sanitizer.bypassSecurityTrustHtml(content);
}
}
I added it in "declarations" of app.module.ts file as well as its import at the top of the file.
Rendering the source code in the console :

Title service in angular2

I have used the Tile service of Angular, and title are getting set successfully.
Here is the code:
import { Component, OnInit } from '#angular/core';
import { Title } from '#angular/platform-browser';
#Component({
selector: 'app-homepage',
templateUrl: './homepage.component.html',
styleUrls: ['./homepage.component.css']
})
export class HomepageComponent implements OnInit {
constructor(private titleService: Title) { }
ngOnInit() {
this.titleService.setTitle('homepage first title');
}
}
but the problem is that when i check the title change through "view page source", none of the changes are getting reflected and the default title in index page is showing , what can i do to resolve this.
View page source is the plain index.html source file (like you have it on your/server file system). No JavaScript is executed or anything, so obviously nothing will show.
If you would like to have that the application is already compiled, take a look at NgUniversal, to leverage server side rendering. Not sure if that will work for your use-case though.

Categories

Resources