วิธีการตั้งค่า <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

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

ตัวอย่างพลั่ว


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 ทรัพยากร" II เปลี่ยนให้this.sanitizer.bypassSecurityTrustResourceUrl(url)ทำงานได้ดี มีความคิดอะไรที่จะผิดพลาดได้บ้าง?
Kosmonaft

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

วิธีนี้ใช้ได้ผลสำหรับฉันตั้งแต่ฉันใช้สิ่งนี้ในที่เดียว มิฉะนั้นแนวทางของท่อจะดีกว่า
Narek Tootikian

@Pang มันทำงานอย่างไร? ฉันมีปัญหาเดียวกันฉันต้องการเพิ่มพารามิเตอร์ใน url ฉันใช้รหัสเหล่านี้ "@Input () parameterForFB: number = this.selectedStudent.schoolId url: string =" designs.mydeievents.com/jq-3d-flip-book /index.html?id=$ {parameterForFB} "; urlSafe: SafeResourceUrl;" แต่ไม่ทำงานกับปัญหาในพารามิเตอร์
Arjun Walmiki

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>

นั่นคือคนทั้งหมด !!!


7
constructor(
 public sanitizer: DomSanitizer, ) {

 }

ฉันดิ้นรนมา 4 ชั่วโมง ปัญหาอยู่ในแท็ก img เมื่อคุณใช้วงเล็บเหลี่ยมเป็น 'src' ex: [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 ติดตั้ง safe-pipe หรือ yarn add safe-pipe สิ่งนี้จะเก็บการอ้างอิงไว้ในการอ้างอิงของคุณในไฟล์ package.json ซึ่งคุณควรจะเริ่มต้นโครงการ Angular ใหม่แล้ว

  2. เพิ่มโมดูล SafePipeModule ไปยัง NgModule.imports ในไฟล์โมดูล Angular ของคุณดังนี้:

    import { SafePipeModule } from 'safe-pipe';
    
    @NgModule({
        imports: [ SafePipeModule ]
    })
    export class AppModule { }
    
    
  3. เพิ่ม pipe ปลอดภัยไปยังองค์ประกอบในเทมเพลตสำหรับองค์ประกอบ Angular ที่คุณกำลังนำเข้าสู่ 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ünterZö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> ในความเป็นจริงคุณสามารถใช้มันเพื่อ inplay เอกสาร desplay เกินไป ..หากคุณมีปัญหาใด ๆ เมื่อใช้แท็กวิดีโอฉันอยู่ที่นี่;)
Smaillns
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.