Как установить <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]безуспешно.

TJ.
источник

Ответы:

344

Обновление v8

Приведенные ниже ответы работают, но подвергают ваше приложение угрозам безопасности XSS! , Вместо использования this.sanitizer.bypassSecurityTrustResourceUrl(url)рекомендуется использоватьthis.sanitizer.sanitize(SecurityContext.URL, url)

Обновить

Для версии RC.6 ^ используйте DomSanitizer

Plunker

И хорошим вариантом для этого является использование чистой трубы:

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>

Plunker

Если вы используете 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';

Образец плунжера

yurzui
источник
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>. Но это не работает с ошибкой «небезопасное значение». Пожалуйста, помогите
Безумная Роза
1
@Insane Rose Я думаю, это должно быть. [src]="url | safe"Просто снимите скобки
yurzui
7
@yurzui Я последовал вашей рекомендации для обновленной версии v8. Однако при использовании 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);      
    }
}
vikvincer
источник
Этот подход работает для меня, так как я использую это в 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

Это работает мне до 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>

вот все люди !!!

Lrodriguez84
источник
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 для безопасной трубы, который вы можете найти здесь . К вашему сведению, это работало в Angular 9.1.3, я не пробовал этого в других версиях Angular. Вот как вы добавите это шаг за шагом:

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

  2. Добавьте модуль SafePipeModule в NgModule.imports в файле модуля Angular следующим образом:

    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>

LRitter
источник
-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>
Janki
источник
-8

Поздравляю! ¨ ^^ У меня есть простое и эффективное решение для вас, да!

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

[attr.src] вместо src "video.url", а не {{video.url}}

Большой ;)

Smaillns
источник
5
Это не имеет значения для строковых значений.
Гюнтер Цохбауэр
1
это не работает Получение сообщения об ошибкеunsafe value used in a resource URL context
Дерек
Таким образом, вы можете использовать тег видео html5, но если вы настаиваете на использовании iframe (по многим причинам;), посмотрите другие решения, которые используют DomSanitizationService ..
Smaillns
так что если вы ищете использование тега 'video', это будет <video> <source [src]=video.url type="video/mp4" /> Browser not supported </video> на самом деле так, вы также можете использовать его для заказа документов. Если у вас возникли проблемы при использовании тега video, я здесь;)
Smaillns