I have a custom frontend application built in angular 2 to display the wordpress posts.
I call the rest api as documented to get the post I want
/wp-json/wp/v2/posts/6
And that gives me the object that I use to populate the page, inside the object is the key content which has all of the content written into the post including all embeded media.
content: {rendered: "<iframe src="xxx"></iframe> lorem ipsum <img src="xxx"/>", protected: false}
I display it in angular by doing along the lines of
{{data.content.rendered}}
This will correctly display the text and the images but the iframe wont be rendered and I will get and error in the console.
WARNING: sanitizing HTML stripped some content (see http://g.co/ng/security#xss).
I read around and some people mentioned the DomSanitizer to fix this, is this the only way possible and what are the security risks of this method.
Alternativly is there any way to modify the wordpress to send back the links embeded in the post in their own key within the object?
edit - after checking out the issue at https://github.com/angular/angular/issues/10145 and using the angular documentation at https://angular.io/api/platform-browser/DomSanitizer, I am still having the issue of the iframe not displaying sadly. The domsanitizer wrapped my display object in another object called changingThisBreaksApplicationSecurity but that didn't display the iframe
Edit 2 - Component
import { Component, OnInit, Input } from '@angular/core';
import {SharedService} from '../services/shared.service';
import {Location} from '@angular/common';
import {Router} from '@angular/router';
import {LocalStorageService} from
'../services/local.service';
import { ActivatedRoute } from '@angular/router';
import { NgZone } from '@angular/core';
import { ApiService } from '../services/api.service';
@Component({
selector: 'app-page',
templateUrl: 'page.template.html',
styleUrls: ['page.scss'],
providers: []
})
export class PageComponent implements OnInit {
pageData;
loading = true;
private sub: any;
hide = false;
constructor(private sharedService: SharedService, private local: LocalStorageService, private api: ApiService, private router: Router, private _location: Location) { }
ngOnInit() {
this.pageData = this.sharedService.pageData ? this.sharedService.pageData : this.local.getItem('pageData')
if(this.pageData){
this.api.getWPData(this.pageData.id)
.subscribe((data) =>{
this.pageData = data;
this.loading = false;
},
err =>{
console.log('There was an error please contact the system administrator');
this.loading=false;
})
}
toggleSynopsis = () =>{
this.hide = !this.hide;
}
testfun = () =>{
this.router.navigate(['/']);
}
}
Template
<div *ngIf="!loading">
<!-- <app-tiles></app-tiles> -->
<div class="container main-text" *ngIf="pageData">
<div class="content">
<h1 class="title is-1 page-title">{{pageData.title.rendered}}</h1>
<h2 class="subtitle is-2 page-subtitle">{{pageData.wps_subtitle}}</h2>
<article class="message is-dark" [ngClass]="{'hidden': hide}">
<div class="message-header">
<p>Synopsis</p>
<button class="delete" aria-label="delete" (click)="toggleSynopsis()"></button>
</div>
<div class="message-body" [innerHtml]="pageData.excerpt.rendered">
<!-- {{pageDate.excerpt.rendered}} -->
</div>
</article>
<p class=" text-body " [innerHtml]="pageData.content.rendered ">
</p>
</div>
</div>
<app-goback (click)="testfun()"></app-goback>
<app-footer></app-footer>
</div>
Sorry for the formatting im on mobile
After some work I found you can pass the data through multiple of the angular sanitizers. Due to the iframe being in the object I had to first pass it through the bypassSecurityTrustHtml by followed by the bypassSecurityTrustResourceUrl.
import { DomSanitizer, SafeResourceUrl, SafeHtml , SafeUrl} from '@angular/platform-browser';
constructor(public sanitizer: DomSanitizer)
this.iframeUrl =
this.sanitizer.bypassSecurityTrustHtml(this.pageData.iframe);
this.iframeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.iframeUrl);
after doing that I was able to see the iframe and video.