使用Angular 2的资源URL上下文中使用的不安全值

时间:2016-06-20 16:39:26

标签: angular typescript

由于升级到最新的Angular 2版本候选版本,我的img标签会出错。

img标签:

<img class='photo-img' [hidden]="!showPhoto1" src='{{theMediaItem.photoURL1}}'>

生成浏览器错误:

ORIGINAL EXCEPTION: Error: unsafe value used in a resource URL context

网址的价值是:

http://veeu-images.s3.amazonaws.com/media/userphotos/116_1464645173408_cdv_photo_007.jpg

修改

我已经尝试过在另一个解决方案中提出的建议,即这个问题应该是重复的,但是我得到了同样的错误。

我已将以下代码添加到控制器:

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

@Component({
  templateUrl: 'build/pages/veeu/veeu.html'
})
export class VeeUPage {
  static get parameters() {
    return [[NavController], [App], [MenuController], [DomSanitizationService]];
  }

  constructor(nav, app, menu, sanitizer) {

    this.app = app;
    this.nav = nav;
    this.menu = menu;
    this.sanitizer = sanitizer;

    this.theMediaItem.photoURL1 = this.sanitizer.bypassSecurityTrustUrl(this.mediaItems[1].url);
  }

我仍然收到相同的错误消息。

EDIT2:

我还将html更改为:

<img class='photo-img' [hidden]="!showPhoto1" [src]='theMediaItem.photoURL1'>

我仍然收到相同的错误消息

9 个答案:

答案 0 :(得分:115)

方法1:

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

...

constructor(public sanitizer: DomSanitizer){}

...然后在HTML中:

    <iframe [src]='sanitizer.bypassSecurityTrustResourceUrl(myurl)' width="640" height="360" frameborder="0"
        webkitallowfullscreen mozallowfullscreen allowfullscreen>
    </iframe>

方法2:

我必须首先在代码中进行清理,因为Vimeo不会在Edge

上最大化

这只是一个例子,重点是,首先在代码中清理,但是你喜欢

对象界面:

import { SafeUrl } from '@angular/platform-browser';
export class Book {
   constructor(public title: string, public videoURL?: SafeUrl) {}
}

服务(例如):

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { Book } from '../features/models/book';
import { DomSanitizer } from '@angular/platform-browser';

@Injectable()

export class BookService {
    constructor(
        private sanitizer: DomSanitizer
    ) {}
    getBooks (): Observable<Book[]> {    
        return new Observable( observer => {
            observer.next(
                    new Book(
                        'Some Book Title', 
                        this.sanitizer.bypassSecurityTrustResourceUrl(
                           'https://player.vimeo.com/video/12345678'
                        )
                    ),
                    new Book(
                        'Second BookTitle',
                        this.sanitizer.bypassSecurityTrustResourceUrl(
                            'https://player.vimeo.com/video/91011121'
                        )
                    )
                )
            });

    }
}

答案 1 :(得分:73)

我正在使用rc.4,此方法适用于ES2015(ES6):

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

@Component({
  templateUrl: 'build/pages/veeu/veeu.html'
})
export class VeeUPage {
  static get parameters() {
    return [NavController, App, MenuController, DomSanitizationService];
  }

  constructor(nav, app, menu, sanitizer) {

    this.app = app;
    this.nav = nav;
    this.menu = menu;
    this.sanitizer = sanitizer;    
  }

  photoURL() {
    return this.sanitizer.bypassSecurityTrustUrl(this.mediaItems[1].url);
  }
}

在HTML中:

<iframe [src]='photoURL()' width="640" height="360" frameborder="0"
    webkitallowfullscreen mozallowfullscreen allowfullscreen>
</iframe>

使用函数将确保在清理后值不会更改。另请注意,您使用的清理功能取决于上下文。

对于图片,bypassSecurityTrustUrl可以使用,但是对于其他用途,您需要参考文档

https://angular.io/docs/ts/latest/api/platform-browser/index/DomSanitizer-class.html

答案 2 :(得分:17)

解决此问题的最优雅方法:使用管道。 Here is example (my blog).因此,您只需使用url | safe管道即可绕过安全性。

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

答案 3 :(得分:13)

您可以将清理程序公开给视图,或者公开将调用转发给bypassSecurityTrustUrl的方法

<img class='photo-img' [hidden]="!showPhoto1" 
    [src]='sanitizer.bypassSecurityTrustUrl(theMediaItem.photoURL1)'>

答案 4 :(得分:9)

使用安全管道对其进行修复。

  • 创建一个安全的管道(如果您没有)。

    ng g c管道安全

  • 在app.module.ts中添加安全管道

    声明:[  安全管道  ]

  • 在您的ts中声明安全管道

导入Dom消毒剂和安全管道以安全访问网址

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

-使用src网址添加安全

<iframe width="900" height="500" [src]="link | safe"/>

答案 5 :(得分:2)

Angular默认将所有值视为不可信。当通过属性,属性,样式,类绑定或插值将值从模板插入DOM时,Angular会清理并转义不受信任的值。

因此,如果您要直接操作DOM并插入内容,则需要对其进行清理,否则Angular会遇到错误。

我为此创建了管道 SanitizeUrlPipe

import { PipeTransform, Pipe } from "@angular/core";
import { DomSanitizer, SafeHtml } from "@angular/platform-browser";

@Pipe({
    name: "sanitizeUrl"
})
export class SanitizeUrlPipe implements PipeTransform {

    constructor(private _sanitizer: DomSanitizer) { }

    transform(v: string): SafeHtml {
        return this._sanitizer.bypassSecurityTrustResourceUrl(v);
    }
}

这就是您可以使用的方式

<iframe [src]="url | sanitizeUrl" width="100%" height="500px"></iframe>

如果您想添加HTML,那么 SanitizeHtmlPipe 可以提供帮助

import { PipeTransform, Pipe } from "@angular/core";
import { DomSanitizer, SafeHtml } from "@angular/platform-browser";

@Pipe({
    name: "sanitizeHtml"
})
export class SanitizeHtmlPipe implements PipeTransform {

    constructor(private _sanitizer: DomSanitizer) { }

    transform(v: string): SafeHtml {
        return this._sanitizer.bypassSecurityTrustHtml(v);
    }
}

了解有关角度安全性here的更多信息。

答案 6 :(得分:0)

import {DomSanitizationService} from '@angular/platform-browser';
@Component({
 templateUrl: 'build/pages/veeu/veeu.html'
 })
  export class VeeUPage {
     trustedURL:any;
      static get parameters() {
               return [NavController, App, MenuController, 
              DomSanitizationService];
        }
      constructor(nav, app, menu, sanitizer) {
        this.app = app;
        this.nav = nav;
        this.menu = menu;
        this.sanitizer = sanitizer;  
        this.trustedURL  = sanitizer.bypassSecurityTrustUrl(this.mediaItems[1].url);
        } 
 }



 <iframe [src]='trustedURL' width="640" height="360" frameborder="0"
   webkitallowfullscreen mozallowfullscreen allowfullscreen>
</iframe>


User property binding instead of function.

答案 7 :(得分:0)

  

我通常如下添加单独的safe pipe可重用组件

# 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 :(得分:0)

可以将图像设置为背景图像,以避免出现unsafe url错误:

<div [style.backgroundImage]="'url(' + imageUrl + ')'" class="show-image"></div>

CSS:

.show-image {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    background-size: cover;        
}