Jak ustawić <iframe src = „…”> bez powodowania wyjątku „niebezpieczna wartość”?

164

Pracuję nad tutorialem dotyczącym ustawiania iframe srcatrybutu:

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

Powoduje to wyjątek:

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

Próbowałem już używać wiązań [src]bez powodzenia.

TJ.
źródło

Odpowiedzi:

344

Zaktualizuj v8

Poniższe odpowiedzi działają, ale narażają Twoją aplikację na zagrożenia bezpieczeństwa XSS! . Zamiast używać this.sanitizer.bypassSecurityTrustResourceUrl(url), zaleca się użyciethis.sanitizer.sanitize(SecurityContext.URL, url)

Aktualizacja

Dla wersji RC.6 ^ użyj DomSanitizer

Plunker

A dobrą opcją jest użycie do tego czystej rury:

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

pamiętaj, aby dodać nowe SafePipedo declarationstablicy AppModule. ( jak widać w dokumentacji )

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

html

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

Plunker

Jeśli używasz embedtagu, może to być dla Ciebie interesujące:


Stara wersja RC.5

Możesz wykorzystać w DomSanitizationServicenastępujący sposób:

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

A następnie powiąż urlw swoim szablonie:

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

Nie zapomnij dodać następujących importów:

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

Próbka Plunker

yurzui
źródło
1
@FugueWeb To dlatego, że ionic2 używa obecnie kątowego RC4. github.com/driftyco/ionic/blob/master/…
yurzui
2
Używam Ionic2. Deklaruję fajkę Pipe({ name: 'safe' }) export class SafePipe implements PipeTransform { constructor(private sanitizer: DomSanitizer) {} transform(url): any { return this.sanitizer.bypassSecurityTrustResourceUrl(url); } } iw szablonie wzywam <iframe width="100%" height="315" src="{{url}} | safe" frameborder="0" allowfullscreen></iframe>. Ale to nie działa z błędem „niebezpieczna wartość”. Proszę o pomoc
Insane Rose
1
@Insane Rose chyba powinno być [src]="url | safe"Po prostu usuń nawiasy
yurzui
7
@yurzui Postępowałem zgodnie z twoją rekomendacją dotyczącą zaktualizowanej wersji v8. Jednak kiedy używam, pojawia this.sanitizer.sanitize(SecurityContext.URL, url)się komunikat o błędzie „BŁĄD Błąd: niebezpieczna wartość używana w kontekście adresu URL zasobu”. I zmień to na this.sanitizer.bypassSecurityTrustResourceUrl(url)działa dobrze. Masz jakiś pomysł, co może być nie tak?
Kosmonaft
2
this.sanitizer.sanitize(SecurityContext.URL, url)nie działa i this.sanitizer.bypassSecurityTrustResourceUrl(url)działa, ale podnosi problem z dużą luką w zabezpieczeniach w analizie kodu statycznego, co uniemożliwia mi przeniesienie tego do produkcji. Potrzebujesz sposobu, aby to naprawić
cjkumaresh
28

Ten działa dla mnie.

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
źródło
To podejście działa dla mnie, ponieważ używam tego w 1 miejscu. W przeciwnym razie podejście rurowe jest lepsze.
Narek Tootikian
@Pang Jak to działa? mam ten sam problem, który chcę dodać mój parametr w adresie URL Używam tego kodu „@Input () parametrForFB: number = this.selectedStudent.schoolId url: string =" designs.mydeievents.com/jq-3d-flip-book /index.html?id=$ {parameterForFB} "; urlSafe: SafeResourceUrl;" ale nie działa problem z parametrem.
Arjun Walmiki
15

Działa mi to na 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>

to wszyscy ludzie !!!

Lrodriguez84
źródło
7
constructor(
 public sanitizer: DomSanitizer, ) {

 }

Walczyłem przez 4 godziny. problem był w tagu img. Kiedy używasz nawiasu kwadratowego do 'src', np. [Src]. nie możesz użyć tego wyrażenia kątowego {{}}. po prostu podajesz bezpośrednio z przykładu obiektu poniżej. jeśli podasz wyrażenie kątowe {{}}. pojawi się błąd interpolacji.

  1. Najpierw użyłem ngFor do iteracji krajów

    *ngFor="let country of countries"
    
  2. po drugie umieścisz to w tagu img. to jest to.

    <img [src]="sanitizer.bypassSecurityTrustResourceUrl(country.flag)"
    height="20" width="20" alt=""/>
    
Kumaresan Perumal
źródło
Należy pamiętać, że umieszczenie wywołania funkcji w kodzie HTML jest złym pomysłem, ponieważ będzie wywoływane za każdym razem, gdy ChangeDetector będzie sprawdzać zmiany.
karoluS
1

Natknąłem się również na ten problem, ale aby użyć bezpiecznej rury w moim module kątowym, zainstalowałem pakiet safe-pipe npm, który możesz znaleźć tutaj . FYI, to działało w Angular 9.1.3, nie próbowałem tego w żadnej innej wersji Angular. Oto jak dodajesz to krok po kroku:

  1. Zainstaluj pakiet poprzez npm install safe-pipe lub yarn add safe-pipe. Spowoduje to zapisanie odniesienia do niego w zależnościach w pliku package.json, który powinieneś mieć już od rozpoczęcia nowego projektu Angular.

  2. Dodaj moduł SafePipeModule do NgModule.imports w pliku modułu Angular w następujący sposób:

    import { SafePipeModule } from 'safe-pipe';
    
    @NgModule({
        imports: [ SafePipeModule ]
    })
    export class AppModule { }
    
    
  3. Dodaj bezpieczną rurkę do elementu w szablonie komponentu Angular, który importujesz do swojego NgModule w ten sposób:

<element [property]="value | safe: sanitizationType"></element>
  1. Oto kilka konkretnych przykładów elementu safePipe w elemencie 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
źródło
-1

Zwykle dodaję oddzielny bezpieczny element wielokrotnego użytku do rur, jak poniżej

# 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
źródło
-8

Gratulacje! ¨ ^^ Mam dla Ciebie łatwe i wydajne rozwiązanie, tak!

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

[attr.src] zamiast src „video.url” i nie {{video.url}}

Świetny ;)

Smaillns
źródło
5
To nie ma znaczenia dla wartości ciągów.
Günter Zöchbauer
1
to nie działa. Pojawia się komunikat o błędzieunsafe value used in a resource URL context
Derek Liang
Możesz więc użyć tagu wideo html5, ale jeśli nalegasz na użycie iframe (z wielu powodów;) zobacz inne rozwiązania, które używają DomSanitizationService ..
Smaillns
więc jeśli szukasz tagu 'video', w rzeczywistości będzie tak <video> <source [src]=video.url type="video/mp4" /> Browser not supported </video> , możesz go użyć również do wysyłania dokumentów ... jeśli masz problemy z tagiem wideo, jestem tutaj;)
Smaillns