¿Cómo establecer <iframe src = "..."> sin causar la excepción de "valor inseguro"?

164

Estoy trabajando en un tutorial que involucra la configuración de un iframe srcatributo:

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

Esto arroja una excepción:

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

Ya he intentado usar enlaces [src]sin éxito.

TJ
fuente

Respuestas:

344

Actualización v8

¡Las respuestas a continuación funcionan pero exponen su aplicación a riesgos de seguridad XSS! . En lugar de usar this.sanitizer.bypassSecurityTrustResourceUrl(url), se recomienda usarthis.sanitizer.sanitize(SecurityContext.URL, url)

Actualizar

Para la versión RC.6 ^ use DomSanitizer

Saqueador

Y una buena opción es usar tubería pura para eso:

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);
  }
} 

recuerde agregar su nuevo SafePipea la declarationsmatriz de AppModule. ( como se ve en la documentación )

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

html

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

Saqueador

Si usa la embedetiqueta, esto podría ser interesante para usted:


Versión anterior RC.5

Puede aprovechar DomSanitizationServiceasí:

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

Y luego únete a urltu plantilla:

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

No olvide agregar las siguientes importaciones:

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

Muestra de saqueador

yurzui
fuente
1
@FugueWeb Eso se debe a que ionic2 está utilizando RC4 angular hoy. github.com/driftyco/ionic/blob/master/…
yurzui
2
Estoy usando Ionic2. Declaro una tubería Pipe({ name: 'safe' }) export class SafePipe implements PipeTransform { constructor(private sanitizer: DomSanitizer) {} transform(url): any { return this.sanitizer.bypassSecurityTrustResourceUrl(url); } } y en plantilla llamo <iframe width="100%" height="315" src="{{url}} | safe" frameborder="0" allowfullscreen></iframe>. Pero no funciona con el error 'valor inseguro'. Por favor ayuda
Insane Rose
1
@Insane Rose, supongo que debería ser [src]="url | safe"Solo quite los corchetes
yurzui
77
@yurzui Seguí tu recomendación para la v8 actualizada. Sin embargo, cuando lo uso this.sanitizer.sanitize(SecurityContext.URL, url)me sale un error "Error de ERROR: valor inseguro utilizado en un contexto de URL de recurso" II lo cambio para que this.sanitizer.bypassSecurityTrustResourceUrl(url)funcione bien. ¿Alguna idea de lo que puede estar mal?
Kosmonaft
2
this.sanitizer.sanitize(SecurityContext.URL, url)no funciona y this.sanitizer.bypassSecurityTrustResourceUrl(url)funciona, pero plantea un problema de vulnerabilidad de alta seguridad en el análisis de código estático, lo que me impide pasar esto a producción. Necesito una manera de arreglar esto
cjkumaresh
28

Esta funciona para mí.

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);      
    }
}
vikvincer
fuente
Este enfoque funciona para mí ya que lo uso en 1 lugar. De lo contrario, el enfoque de la tubería es mejor.
Narek Tootikian
@Pang ¿Cómo funciona? tengo el mismo problema que quiero agregar mi parámetro en la url estoy usando este código "@Input () parameterForFB: number = this.selectedStudent.schoolId url: string =" designs.mydeievents.com/jq-3d-flip-book /index.html?id=$ {parameterForFB} "; urlSafe: SafeResourceUrl;" pero no funciona problema de cara en el parámetro.
Arjun Walmiki
15

Esto me funciona a 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>

¡¡¡eso es todo amigos!!!

Lrodriguez84
fuente
7
constructor(
 public sanitizer: DomSanitizer, ) {

 }

Había estado luchando por 4 horas. El problema estaba en la etiqueta img. Cuando usa corchetes para 'src', por ejemplo: [src]. no puede usar esta expresión angular {{}}. solo das directamente de un ejemplo de objeto a continuación. si le das una expresión angular {{}}. Obtendrá un error de interpolación.

  1. primero usé ngFor para iterar los países

    *ngFor="let country of countries"
    
  2. segundo pones esto en la etiqueta img. eso es todo.

    <img [src]="sanitizer.bypassSecurityTrustResourceUrl(country.flag)"
    height="20" width="20" alt=""/>
    
Kumaresan Perumal
fuente
Tenga en cuenta que poner una llamada a la función dentro de HTML es una mala idea porque se llamará cada vez que ChangeDetector verifique los cambios.
karolus
1

También me encontré con este problema, pero para usar una tubería segura en mi módulo angular, instalé el paquete npm safe-pipe, que puedes encontrar aquí . Para su información, esto funcionó en Angular 9.1.3, no lo he probado en ninguna otra versión de Angular. Así es como lo agrega paso a paso:

  1. Instale el paquete a través de npm install safe-pipe o hilo agregue safe-pipe. Esto almacenará una referencia a él en sus dependencias en el archivo package.json, que ya debería tener al comenzar un nuevo proyecto angular.

  2. Agregue el módulo SafePipeModule a NgModule.imports en su archivo de módulo angular de la siguiente manera:

    import { SafePipeModule } from 'safe-pipe';
    
    @NgModule({
        imports: [ SafePipeModule ]
    })
    export class AppModule { }
    
    
  3. Agregue la tubería segura a un elemento en la plantilla para el componente angular que está importando a su NgModule de esta manera:

<element [property]="value | safe: sanitizationType"></element>
  1. Estos son algunos ejemplos específicos de safePipe en un elemento html:
<div [style.background-image]="'url(' + pictureUrl + ')' | safe: 'style'" class="pic bg-pic"></div>
<img [src]="pictureUrl | safe: 'url'" class="pic" alt="Logo">
<iframe [src]="catVideoEmbed | safe: 'resourceUrl'" width="640" height="390"></iframe>
<pre [innerHTML]="htmlContent | safe: 'html'"></pre>

LRitter
fuente
-1

Por lo general, agrego un componente reutilizable de tubería segura separado de la siguiente manera

# 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>
Janki
fuente
-8

Enhorabuena! ¨ ^^ Tengo una solución fácil y eficiente para ti, ¡sí!

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

[attr.src] en lugar de src "video.url" y no {{video.url}}

Excelente ;)

Smaillns
fuente
55
Eso no hace una diferencia para los valores de cadena.
Günter Zöchbauer
1
No funciona. Recibiendo mensaje de errorunsafe value used in a resource URL context
Derek Liang
Por lo tanto, puede usar la etiqueta de video html5, pero si insiste en usar iframe (por muchas razones;) vea otras soluciones que usan DomSanitizationService ..
Smaillns
así que si está buscando usar la etiqueta de 'video', será así <video> <source [src]=video.url type="video/mp4" /> Browser not supported </video> , de hecho, puede usarla para mostrar documentos también ... si tiene algún problema al usar la etiqueta de video, estoy aquí;)
Smaillns