52 votes

La désinfection de l'URL entraîne l'actualisation de la vidéo YouTube intégrée.

J'ai un problème avec mon application AngularJS 2 (j'utilise la version RC5 d'AngularJS 2). Il semble qu'une URL aseptisée déclenche une détection de changement qui met ensuite à jour le fichier div ci-dessous alors que l'état de mon composant n'a pas changé.

Du point de vue de l'utilisateur, cela se manifeste par le rechargement de la vidéo en cours de lecture.

Donc, dans ma vue des composants, j'ai :

<div *ngIf="isVideo(item)">
   <iframe [src]="getTrustedYouTubeUrl(item)" scrolling="no" frameborder="0" allowfullscreen></iframe>          
</div>

L'implémentation de la fonction ci-dessus dans le code du composant est la suivante :

getTrustedYouTubeUrl(linkedVideo:LinkedVideoModel) {
    return this.sanitizer.bypassSecurityTrustResourceUrl(linkedVideo.video.url);
}    

Dans le débogueur, je vois que la division est rafraîchie assez souvent, par quelque chose déclenché dans le cadre d'AngularJS 2.

Le problème disparaît si je remplace l'extrait HTML ci-dessus par une URL codée en dur :

<div *ngIf="isVideo(item)">
   <iframe src="<hardcoded youtube url here>" scrolling="no" frameborder="0" allowfullscreen></iframe>          
</div> 

Je soupçonne donc que la désinfection des URL en est la cause.

Quelqu'un peut-il m'indiquer la bonne direction ? Un exemple fonctionnel de vidéos YouTube intégrées dont l'URL est liée à une propriété du composant, par exemple ?

91voto

ayls Points 310

J'ai compris.

Pour toute personne intéressée. Le problème était l'utilisation de cette fonction dans mon html

   [src]="getTrustedYouTubeUrl(item)"

L'effet secondaire de rechargement a disparu une fois que j'ai modifié le code pour calculer l'url sécurisée lorsque les données sont chargées dans mon service et que j'ai changé la liaison iframe en ceci

    <iframe [src]="item.video.safeUrl" scrolling="no" frameborder="0" allowfullscreen></iframe>    

Notez quer je suis maintenant lié à une propriété.

1 votes

Ce même problème vient d'apparaître pour moi après des mois d'utilisation de [src]='sanitizer.bypassSecurityTrustResourceUrl(this.Url)'. Je n'ai aucune idée de la raison pour laquelle cela a commencé (angular 4.4 et je ne l'ai pas mis à jour). Cependant, votre solution l'a résolu. Merci !

1 votes

@Anthony comment avez-vous résolu le problème exactement ? J'ai le même problème maintenant, j'utilise Angular 2. J'utilise également [src]='sanitizer.bypassSecurityTrustResourceUrl(this.Url), mais lorsque je lie src à une propriété, j'obtiens "ERROR Error : Required a safe ResourceURL, got a URL (see g.co/ng/security#xss )" message.

0 votes

@handris Voir ma réponse ci-dessus.

42voto

yurzui Points 85802

J'essaierais de l'utiliser avec tuyau pur

Angular n'exécute un pipe pur que lorsqu'il détecte une modification pure de l'objet valeur d'entrée. Un changement pur est soit un changement de valeur d'entrée primitive (String, Number, Boolean, Symbol), soit un changement de référence d'objet. primitive (String, Number, Boolean, Symbol) ou une référence d'objet modifiée (Date, Array). (Date, Tableau, Fonction, Objet).

Le tuyau pourrait ressembler à ( RC.6 - DomSanitizer devient au lieu de DomSanitizationService ):

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

Et l'utiliser comme le suivant :

<iframe [src]="url | safe" frameborder="0" allowfullscreen></iframe> 

Exemple de Plunker (essaie d'appuyer sur le bouton)

0 votes

Merci, je vais essayer. J'ai déjà trouvé une autre solution de contournement, mais cette idée semble intéressante.

0 votes

Impossible de récupérer /SafeValue%20must%20use%20[property]=binding:%20https://www.youtube.com/embed/wyVM1evRxNw%20(see%20http://g.co/ng/security

1 votes

Belle solution ! Plunker ne fonctionne pas pour une raison quelconque, voici une version mise à jour Exemple de Plunker (en utilisant Angular v4.2.3)

14voto

Anthony Points 385

J'ai combiné les réponses précédentes pour le faire fonctionner de cette façon :

component.ts (seulement les parties pertinentes)

import { DomSanitizer } from '@angular/platform-browser';

constructor( 
  private sanitizer: DomSanitizer   
) {
  this.sanitizer = sanitizer;
}

ngOnInit() {
 this.getTrustedUrl('http://someUrl');
}

getTrustedUrl(url:any){ 
 this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(url);
}

modèle.html

<iframe      
  [src]='this.safeUrl'>
</iframe>

0 votes

Juste ce dont j'avais besoin.... Cette approche de l'application permet à l'assainisseur de ne fonctionner qu'une seule fois.

0 votes

Ce problème est résolu par mon auto flashage de google maps. Merci

8voto

Murhaf Sousli Points 1163

Vous pouvez conserver votre solution originale et utiliser simplement changeDetection: ChangeDetectionStrategy.OnPush

<div *ngIf="isVideo(item)">
   <iframe [src]="getTrustedYouTubeUrl(item)" scrolling="no" frameborder="0" allowfullscreen></iframe>          
</div>

1 votes

Cela fonctionne pour moi :)

3voto

Daniel Rocci Points 31
<iframe #ytplayer  width="100%" height="235" frameborder="0" src="">
</iframe>    

@ViewChild('ytplayer', null) ytPlayer: ElementRef;

ngOnInit() {
  this.ytPlayer.nativeElement.src = this.act.iframe;
}

Le rechargement se produit à cause de l'utilisation de sanitizer.bypassSecurityTrustResourceUrl. Nous ne devrions donc pas l'utiliser. Je pense que c'est plus confortable. Merci.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X