Як встановити <iframe src = "...">, не викликаючи винятку "небезпечне значення"?


164

Я працюю над підручником із встановленням iframe srcатрибута:

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

Це кидає виняток:

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

Я вже [src]без успіху намагався використовувати палітурку .

Відповіді:


344

Оновлення v8

Нижче відповіді працюють, але викриваєте вашу заявку ризикам безпеки XSS! . Замість використання this.sanitizer.bypassSecurityTrustResourceUrl(url)рекомендується використовуватиthis.sanitizer.sanitize(SecurityContext.URL, url)

Оновлення

Для версії RC.6 ^ використовуйте DomSanitizer

Плункер

І хорошим варіантом є використання для цього чистої труби:

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

не забудьте додати ваш новий SafePipeдо declarationsмасиву AppModule. ( як видно з документації )

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

html

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

Плункер

Якщо ви використовуєте embedтег, це може бути цікавим для вас:


Стара версія RC.5

Ви можете використовувати DomSanitizationServiceтак:

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

А потім прив’яжіть до urlсвого шаблону:

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

Не забудьте додати наступний імпорт:

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

Зразок Плункер


1
@FugueWeb Це тому, що ionic2 сьогодні використовує кутовий RC4. github.com/driftyco/ionic/blob/master/…
yurzui

2
Я використовую Ionic2. Я оголошую трубу Pipe({ name: 'safe' }) export class SafePipe implements PipeTransform { constructor(private sanitizer: DomSanitizer) {} transform(url): any { return this.sanitizer.bypassSecurityTrustResourceUrl(url); } } і в шаблоні дзвоню <iframe width="100%" height="315" src="{{url}} | safe" frameborder="0" allowfullscreen></iframe>. Але це не працює з помилковим "небезпечним значенням". Будь ласка, допоможіть
Insane Rose

1
@Insane Rose я думаю, це має бути [src]="url | safe"просто зняти дужки
yurzui

7
@yurzui Я дотримувався вашої рекомендації щодо оновленої версії 8. Однак, коли я використовую, this.sanitizer.sanitize(SecurityContext.URL, url)я отримую помилку "Помилка помилки: небезпечне значення, яке використовується в контексті URL-адреси ресурсу", я міняю її на this.sanitizer.bypassSecurityTrustResourceUrl(url)чудову роботу. Будь-яка ідея, що може бути не так?
Космонафт

2
this.sanitizer.sanitize(SecurityContext.URL, url)не працює і не this.sanitizer.bypassSecurityTrustResourceUrl(url)працює, але ставить проблему з високою вразливістю безпеки при аналізі статичного коду, що не дозволяє мені перенести це на виробництво. Потрібен спосіб виправити це
cjkumaresh

28

Цей працює для мене.

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

Цей підхід працює для мене, оскільки я використовую це на 1 місці. Інакше трубовий підхід краще.
Нарек Тоотикян

@Pang Як ​​це працює? у мене є те саме питання, я хочу додати свій параметр у url, я використовую цей код "@Input () parameterForFB: number = this.selectedStudent.schoolId url: string =" designs.mydeievents.com/jq-3d-flip-book /index.html?id=$ {parameterForFB} "; urlSafe: SafeResourceUrl;" але в параметрі не працює проблема обличчя.
Арджун Уолмікі

15

Це підходить мені до кутового 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>

це все, шановні!!!


7
constructor(
 public sanitizer: DomSanitizer, ) {

 }

Я боровся 4 години. проблема була в тезі img. Коли ви використовуєте квадратну дужку для 'src', наприклад: [src]. ви не можете використовувати цей кутовий вираз {{}}. ви просто наводите безпосередньо приклад об'єкта нижче. якщо дати кутовий вираз {{}}. ви отримаєте помилку інтерполяції.

  1. Спочатку я використав ngFor для повторення країн

    *ngFor="let country of countries"
    
  2. по-друге, ви помістите це в тег img. це воно.

    <img [src]="sanitizer.bypassSecurityTrustResourceUrl(country.flag)"
    height="20" width="20" alt=""/>
    

Майте на увазі, що розміщення виклику функції всередині HTML - це погана ідея, оскільки він буде викликатися кожен раз, коли ChangeDetector перевірятиме зміни.
karoluS

1

Я також зіткнувся з цим питанням, але для того, щоб використовувати безпечну трубу в своєму кутовому модулі, я встановив пакет npm безпечної труби, який ви можете знайти тут . FYI, це працювало в Angular 9.1.3, я не пробував цього в будь-яких інших версіях Angular. Ось як ви додаєте його поетапно:

  1. Встановіть пакет через npm встановіть безпечну трубу або пряжу додайте безпечну трубу. Це збереже посилання на нього у ваших залежностях у файлі package.json, яке ви вже повинні мати при запуску нового кутового проекту.

  2. Додайте модуль SafePipeModule в NgModule.imports у файл вашого кутового модуля так:

    import { SafePipeModule } from 'safe-pipe';
    
    @NgModule({
        imports: [ SafePipeModule ]
    })
    export class AppModule { }
    
    
  3. Додайте безпечну трубку до елемента в шаблоні для кутового компонента, який ви імпортуєте у свій NgModule таким чином:

<element [property]="value | safe: sanitizationType"></element>
  1. Ось деякі конкретні приклади safePipe в 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

Я зазвичай додаю окремий компонент для багаторазового використання безпечної труби наступним чином

# 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

Вітаємо! ¨ ^^ У мене є просте та ефективне рішення для вас, так!

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

[attr.src] замість src "video.url", а не {{video.url}}

Чудово;)


5
Це не має значення для рядкових значень.
Günter Zöchbauer

1
це не працює. Повідомлення про помилкуunsafe value used in a resource URL context
Дерек Лян

Так, ви можете використовувати відео тег html5, але якщо ви наполягаєте на використанні iframe (з багатьох причин;), перегляньте інші рішення, які використовують DomSanitizationService ..
Smaillns,

тому якщо ви шукаєте використання тегу "відео", воно буде таким, як <video> <source [src]=video.url type="video/mp4" /> Browser not supported </video> насправді, ви можете використовувати його впорядкованому для того, щоб також знімати документи. Якщо у вас виникли проблеми при використанні
відеотега
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.