How to set iframe src in Angular 2 without causing

2019-01-01 08:53发布

问题:

I am new to Angular 2 without AngularJS experience and working on a tutorial involving the setting of an iframe src attribute:

<iframe width=\"100%\" height=\"300\" src=\"{{video.url}}\"></iframe>

This throws an exception:

Error: unsafe value used in a resource URL context
at DomSanitizationServiceImpl.sanitize...

I have already tried using bindings with [src] with no success. I am probably missing something and I have had a hard time finding a solution to this.

回答1:

Update

For RC.6^ version use DomSanitizer

Plunker

And a good option is using pure pipe for that:

import { Pipe, PipeTransform } from \'@angular/core\';
import { DomSanitizer} from \'@angular/platform-browser\';

@Pipe({ name: \'safe\' })
export class SafePipe implements PipeTransform {
  constructor(private sanitizer: DomSanitizer) {}
  transform(url) {
    return this.sanitizer.bypassSecurityTrustResourceUrl(url);
  }
} 

remember to add your new SafePipe to the declarations array of the AppModule. (as seen on documentation)

@NgModule({
   declarations : [
     ...
     SafePipe
   ],
})

html

<iframe width=\"100%\" height=\"300\" [src]=\"url | safe\"></iframe>

Plunker

If you use embed tag this might be interesting for you:

  • how with angular2 rc.6 disable sanitize on embed html tag which display pdf

Old version RC.5

You can leverage DomSanitizationService like this:

export class YourComponent {
  url: SafeResourceUrl;
  constructor(sanitizer: DomSanitizationService) {
    this.url = sanitizer.bypassSecurityTrustResourceUrl(\'your url\');
  }
}

And then bind to url in your template:

<iframe width=\"100%\" height=\"300\" [src]=\"url\"></iframe>

Don\'t forget to add the following imports:

import { SafeResourceUrl, DomSanitizationService } from \'@angular/platform-browser\';

Plunker sample



回答2:

This one works for me.

import { Component,Input,OnInit} from \'@angular/core\';
import {DomSanitizer,SafeResourceUrl,} from \'@angular/platform-browser\';

@Component({
    moduleId: module.id,
    selector: \'player\',
    templateUrl: \'./player.component.html\',
    styleUrls:[\'./player.component.scss\'],

})
export class PlayerComponent implements OnInit{
    @Input()
    id:string; 
    url: SafeResourceUrl;
    constructor (public sanitizer:DomSanitizer) {
    }
    ngOnInit() {
        this.url = this.sanitizer.bypassSecurityTrustResourceUrl(this.id);      
    }
}


回答3:

This works me to Angular 5.2.0

sarasa.Component.ts

import { Component, OnInit, Input } from \'@angular/core\';
import { DomSanitizer, SafeResourceUrl } from \'@angular/platform-browser\';

@Component({
  selector: \'app-sarasa\',
  templateUrl: \'./sarasa.component.html\',
  styleUrls: [\'./sarasa.component.scss\']
})

export class Sarasa implements OnInit {
  @Input()
  url: string = \"https://www.mmlpqtpkasjdashdjahd.com\";
  urlSafe: SafeResourceUrl;

  constructor(public sanitizer: DomSanitizer) { }

  ngOnInit() {
    this.urlSafe= this.sanitizer.bypassSecurityTrustResourceUrl(this.url);
  }

}

sarasa.Component.html

<iframe width=\"100%\" height=\"100%\" frameBorder=\"0\" [src]=\"urlSafe\"></iframe>

thats all folks!!!



回答4:

constructor(
 public sanitizer: DomSanitizer, ) {

 }

I had been struggling for 4 hours. the problem was in img tag. When you use square bracket to \'src\' ex: [src]. you can not use this angular expression {{}}. you just give directly from an object example below. if you give angular expression {{}}. you will get interpolation error.

  1. first i used ngFor to iterate the countries

    *ngFor=\"let country of countries\"
    
  2. second you put this in the img tag. this is it.

    <img [src]=\"sanitizer.bypassSecurityTrustResourceUrl(country.flag)\"
    height=\"20\" width=\"20\" alt=\"\"/>
    


回答5:

I usually add separate safe pipe reusable component as following

# Add Safe Pipe

import { Pipe, PipeTransform } from \'@angular/core\';
import { DomSanitizer } from \'@angular/platform-browser\';

@Pipe({name: \'mySafe\'})
export class SafePipe implements PipeTransform {
    constructor(private sanitizer: DomSanitizer) {
    }

    public transform(url) {
        return this.sanitizer.bypassSecurityTrustResourceUrl(url);
    }
}
# then create shared pipe module as following 

import { NgModule } from \'@angular/core\'; 
import { SafePipe } from \'./safe.pipe\';
@NgModule({
    declarations: [
        SafePipe
    ],
    exports: [
        SafePipe
    ]
})
export class SharedPipesModule {
}
# import shared pipe module in your native module

@NgModule({
    declarations: [],
    imports: [
        SharedPipesModule,
    ],
})
export class SupportModule {
}
<!-------------------
call your url (`trustedUrl` for me) and add `mySafe` as defined in Safe Pipe
---------------->
<div class=\"container-fluid\" *ngIf=\"trustedUrl\">
    <iframe [src]=\"trustedUrl | mySafe\" align=\"middle\" width=\"100%\" height=\"800\" frameborder=\"0\"></iframe>
</div>


回答6:

Congratulation ! ¨^^ I have an easy & efficient solution for you, yes!

<iframe width=\"100%\" height=\"300\" [attr.src]=\"video.url\"></iframe

[attr.src] instead of src \"video.url\" and not {{video.url}}

Great ;)