Comment définir <iframe src = “…”> sans provoquer une exception `unsafe value`?

164

Je travaille sur un tutoriel impliquant le paramétrage d'un iframe srcattribut:

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

Cela lève une exception:

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

J'ai déjà essayé d'utiliser des liaisons [src]sans succès.

TJ.
la source

Réponses:

344

Mettre à jour v8

Les réponses ci-dessous fonctionnent mais exposent votre application aux risques de sécurité XSS! . Au lieu d'utiliser this.sanitizer.bypassSecurityTrustResourceUrl(url), il est recommandé d'utiliserthis.sanitizer.sanitize(SecurityContext.URL, url)

Mettre à jour

Pour la version RC.6 ^ , utilisez DomSanitizer

Plunker

Et une bonne option consiste à utiliser pure pipe pour cela:

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

n'oubliez pas d'ajouter votre nouveau SafePipeau declarationstableau de l'AppModule. ( comme vu sur la documentation )

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

html

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

Plunker

Si vous utilisez une embedbalise, cela peut être intéressant pour vous:


Ancienne version RC.5

Vous pouvez utiliser DomSanitizationServicecomme ceci:

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

Et puis liez-vous urldans votre modèle:

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

N'oubliez pas d'ajouter les importations suivantes:

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

Échantillon Plunker

yurzui
la source
1
@FugueWeb C'est parce qu'ionic2 utilise aujourd'hui le RC4 angulaire. github.com/driftyco/ionic/blob/master/…
yurzui
2
J'utilise Ionic2. Je déclare un tuyau Pipe({ name: 'safe' }) export class SafePipe implements PipeTransform { constructor(private sanitizer: DomSanitizer) {} transform(url): any { return this.sanitizer.bypassSecurityTrustResourceUrl(url); } } et dans le modèle j'appelle <iframe width="100%" height="315" src="{{url}} | safe" frameborder="0" allowfullscreen></iframe>. Mais cela ne fonctionne pas avec l'erreur «valeur dangereuse». S'il vous plaît aider
Insane Rose
1
@Insane Rose je suppose que ça devrait être [src]="url | safe"Il suffit de supprimer les crochets
yurzui
7
@yurzui J'ai suivi votre recommandation pour la mise à jour v8. Cependant, lorsque j'utilise, this.sanitizer.sanitize(SecurityContext.URL, url)j'obtiens une erreur "ERROR Error: unsafe value used in a resource URL context" II change it to this.sanitizer.bypassSecurityTrustResourceUrl(url)works fine. Une idée de ce qui ne va pas?
Kosmonaft
2
this.sanitizer.sanitize(SecurityContext.URL, url)ne fonctionne pas et this.sanitizer.bypassSecurityTrustResourceUrl(url)fonctionne mais soulève un problème de vulnérabilité de haute sécurité dans l'analyse de code statique, ce qui m'empêche de passer cela en production. Besoin d'un moyen de résoudre ce problème
cjkumaresh
28

Celui-ci fonctionne pour moi.

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
la source
Cette approche fonctionne pour moi puisque je l'utilise en un seul endroit. Sinon, l'approche par tuyau est meilleure.
Narek Tootikian
@Pang Comment ça marche? J'ai le même problème que je veux ajouter mon paramètre dans l'url J'utilise ce code "@Input () parameterForFB: number = this.selectedStudent.schoolId url: string =" designs.mydeievents.com/jq-3d-flip-book /index.html?id=$ {parameterForFB} "; urlSafe: SafeResourceUrl;" mais ne fonctionne pas problème de visage en paramètre.
Arjun Walmiki
15

Cela me fonctionne à 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>

c'est tout le monde !!!

Lrodriguez84
la source
7
constructor(
 public sanitizer: DomSanitizer, ) {

 }

Je luttais depuis 4 heures. le problème était dans la balise img. Lorsque vous utilisez des crochets pour 'src' ex: [src]. vous ne pouvez pas utiliser cette expression angulaire {{}}. vous venez de donner directement à partir d'un exemple d'objet ci-dessous. si vous donnez une expression angulaire {{}}. vous obtiendrez une erreur d'interpolation.

  1. J'ai d'abord utilisé ngFor pour parcourir les pays

    *ngFor="let country of countries"
    
  2. deuxièmement, vous mettez ceci dans la balise img. Ça y est.

    <img [src]="sanitizer.bypassSecurityTrustResourceUrl(country.flag)"
    height="20" width="20" alt=""/>
    
Kumaresan Perumal
la source
Sachez que placer un appel de fonction dans HTML est une mauvaise idée car il sera appelé à chaque fois que ChangeDetector vérifiera les changements.
karoluS
1

J'ai également rencontré ce problème, mais afin d'utiliser un tube sécurisé dans mon module angulaire, j'ai installé le package safe-pipe npm, que vous pouvez trouver ici . FYI, cela a fonctionné dans Angular 9.1.3, je n'ai essayé cela dans aucune autre version d'Angular. Voici comment vous l'ajouter étape par étape:

  1. Installez le package via npm install safe-pipe ou yarn add safe-pipe. Cela stockera une référence à celui-ci dans vos dépendances dans le fichier package.json, que vous devriez déjà avoir au démarrage d'un nouveau projet Angular.

  2. Ajoutez le module SafePipeModule à NgModule.imports dans votre fichier de module angulaire comme ceci:

    import { SafePipeModule } from 'safe-pipe';
    
    @NgModule({
        imports: [ SafePipeModule ]
    })
    export class AppModule { }
    
    
  3. Ajoutez le tube sécurisé à un élément du modèle pour le composant angulaire que vous importez dans votre NgModule de cette façon:

<element [property]="value | safe: sanitizationType"></element>
  1. Voici quelques exemples spécifiques du safePipe dans un élément 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
la source
-1

J'ajoute généralement un composant réutilisable de tuyau de sécurité séparé comme suit

# 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
la source
-8

Félicitations! ¨ ^^ J'ai une solution simple et efficace pour vous, oui!

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

[attr.src] au lieu de src "video.url" et non {{video.url}}

Génial ;)

Smaillns
la source
5
Cela ne fait aucune différence pour les valeurs de chaîne.
Günter Zöchbauer
1
ça ne marche pas. Obtenir un message d'erreurunsafe value used in a resource URL context
Derek Liang
Donc, vous pouvez utiliser la balise vidéo html5, mais si vous insistez pour utiliser iframe (pour de nombreuses raisons;) voir d'autres solutions qui utilisent DomSanitizationService ..
Smaillns
donc si vous cherchez à utiliser la balise 'video', ce sera comme ça <video> <source [src]=video.url type="video/mp4" /> Browser not supported </video> en fait, vous pouvez l'utiliser pour afficher des documents aussi .. si vous avez des problèmes lors de l'utilisation de la balise vidéo, je suis là;)
Smaillns