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.

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


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

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 !!!


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=""/>
    

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>


-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>

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


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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.